mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-26 02:20:48 +00:00
Memory input stream (Simplified version of ReReadableInputStream, which accepts byte array)
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionEnd;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionNop;
|
||||
@@ -55,7 +54,7 @@ import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ProgressListener;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.helpers.streams.SeekableInputStream;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -166,6 +165,21 @@ public class SWFInputStream extends InputStream {
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets position in bytes in the stream
|
||||
*
|
||||
* @param pos Number of bytes
|
||||
*/
|
||||
public void seek(int pos) throws IOException {
|
||||
if (is instanceof SeekableInputStream) {
|
||||
SeekableInputStream sis = (SeekableInputStream) is;
|
||||
sis.seek(pos);
|
||||
}
|
||||
else {
|
||||
throw new IOException("Underlying stream is not a SeekableInputStream");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one byte from the stream
|
||||
*
|
||||
@@ -535,15 +549,6 @@ public class SWFInputStream extends InputStream {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, String path) throws IOException {
|
||||
ReReadableInputStream rri = new ReReadableInputStream(this);
|
||||
return ActionListReader.readActionList(listeners, containerSWFOffset, rri, version, 0, -1, path);
|
||||
}
|
||||
|
||||
public List<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, ReReadableInputStream rri, int maxlen, String path) throws IOException {
|
||||
return ActionListReader.readActionList(listeners, containerSWFOffset, rri, version, (int) rri.getPos(), (int) rri.getPos() + maxlen, path);
|
||||
}
|
||||
|
||||
private static void dumpTag(PrintStream out, int version, Tag tag, int level) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Helper.formatHex((int) tag.getPos(), 8));
|
||||
@@ -1072,251 +1077,244 @@ public class SWFInputStream extends InputStream {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Action readAction(ConstantPool cpool) throws IOException {
|
||||
return readAction(new ReReadableInputStream(this), cpool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one Action from the stream
|
||||
*
|
||||
* @param rri
|
||||
* @return Action or null when ActionEndFlag or end of the stream
|
||||
* @throws IOException
|
||||
*/
|
||||
public Action readAction(ReReadableInputStream rri, ConstantPool cpool) throws IOException {
|
||||
{
|
||||
int actionCode = -1;
|
||||
public Action readAction(ConstantPool cpool) throws IOException {
|
||||
int actionCode = -1;
|
||||
|
||||
try {
|
||||
actionCode = readUI8();
|
||||
if (actionCode == 0) {
|
||||
return new ActionEnd();
|
||||
}
|
||||
if (actionCode == -1) {
|
||||
return null;
|
||||
}
|
||||
int actionLength = 0;
|
||||
if (actionCode >= 0x80) {
|
||||
actionLength = readUI16();
|
||||
}
|
||||
switch (actionCode) {
|
||||
//SWF3 Actions
|
||||
case 0x81:
|
||||
return new ActionGotoFrame(actionLength, this);
|
||||
case 0x83:
|
||||
return new ActionGetURL(actionLength, this, version);
|
||||
case 0x04:
|
||||
return new ActionNextFrame();
|
||||
case 0x05:
|
||||
return new ActionPrevFrame();
|
||||
case 0x06:
|
||||
return new ActionPlay();
|
||||
case 0x07:
|
||||
return new ActionStop();
|
||||
case 0x08:
|
||||
return new ActionToggleQuality();
|
||||
case 0x09:
|
||||
return new ActionStopSounds();
|
||||
case 0x8A:
|
||||
return new ActionWaitForFrame(actionLength, this, cpool);
|
||||
case 0x8B:
|
||||
return new ActionSetTarget(actionLength, this, version);
|
||||
case 0x8C:
|
||||
return new ActionGoToLabel(actionLength, this, version);
|
||||
//SWF4 Actions
|
||||
case 0x96:
|
||||
return new ActionPush(actionLength, this, version);
|
||||
case 0x17:
|
||||
return new ActionPop();
|
||||
case 0x0A:
|
||||
return new ActionAdd();
|
||||
case 0x0B:
|
||||
return new ActionSubtract();
|
||||
case 0x0C:
|
||||
return new ActionMultiply();
|
||||
case 0x0D:
|
||||
return new ActionDivide();
|
||||
case 0x0E:
|
||||
return new ActionEquals();
|
||||
case 0x0F:
|
||||
return new ActionLess();
|
||||
case 0x10:
|
||||
return new ActionAnd();
|
||||
case 0x11:
|
||||
return new ActionOr();
|
||||
case 0x12:
|
||||
return new ActionNot();
|
||||
case 0x13:
|
||||
return new ActionStringEquals();
|
||||
case 0x14:
|
||||
return new ActionStringLength();
|
||||
case 0x21:
|
||||
return new ActionStringAdd();
|
||||
case 0x15:
|
||||
return new ActionStringExtract();
|
||||
case 0x29:
|
||||
return new ActionStringLess();
|
||||
case 0x31:
|
||||
return new ActionMBStringLength();
|
||||
case 0x35:
|
||||
return new ActionMBStringExtract();
|
||||
case 0x18:
|
||||
return new ActionToInteger();
|
||||
case 0x32:
|
||||
return new ActionCharToAscii();
|
||||
case 0x33:
|
||||
return new ActionAsciiToChar();
|
||||
case 0x36:
|
||||
return new ActionMBCharToAscii();
|
||||
case 0x37:
|
||||
return new ActionMBAsciiToChar();
|
||||
case 0x99:
|
||||
return new ActionJump(actionLength, this);
|
||||
case 0x9D:
|
||||
return new ActionIf(actionLength, this);
|
||||
case 0x9E:
|
||||
return new ActionCall(actionLength);
|
||||
case 0x1C:
|
||||
return new ActionGetVariable();
|
||||
case 0x1D:
|
||||
return new ActionSetVariable();
|
||||
case 0x9A:
|
||||
return new ActionGetURL2(actionLength, this);
|
||||
case 0x9F:
|
||||
return new ActionGotoFrame2(actionLength, this);
|
||||
case 0x20:
|
||||
return new ActionSetTarget2();
|
||||
case 0x22:
|
||||
return new ActionGetProperty();
|
||||
case 0x23:
|
||||
return new ActionSetProperty();
|
||||
case 0x24:
|
||||
return new ActionCloneSprite();
|
||||
case 0x25:
|
||||
return new ActionRemoveSprite();
|
||||
case 0x27:
|
||||
return new ActionStartDrag();
|
||||
case 0x28:
|
||||
return new ActionEndDrag();
|
||||
case 0x8D:
|
||||
return new ActionWaitForFrame2(actionLength, this, cpool);
|
||||
case 0x26:
|
||||
return new ActionTrace();
|
||||
case 0x34:
|
||||
return new ActionGetTime();
|
||||
case 0x30:
|
||||
return new ActionRandomNumber();
|
||||
//SWF5 Actions
|
||||
case 0x3D:
|
||||
return new ActionCallFunction();
|
||||
case 0x52:
|
||||
return new ActionCallMethod();
|
||||
case 0x88:
|
||||
return new ActionConstantPool(actionLength, this, version);
|
||||
case 0x9B:
|
||||
return new ActionDefineFunction(actionLength, this, rri, version);
|
||||
case 0x3C:
|
||||
return new ActionDefineLocal();
|
||||
case 0x41:
|
||||
return new ActionDefineLocal2();
|
||||
case 0x3A:
|
||||
return new ActionDelete();
|
||||
case 0x3B:
|
||||
return new ActionDelete2();
|
||||
case 0x46:
|
||||
return new ActionEnumerate();
|
||||
case 0x49:
|
||||
return new ActionEquals2();
|
||||
case 0x4E:
|
||||
return new ActionGetMember();
|
||||
case 0x42:
|
||||
return new ActionInitArray();
|
||||
case 0x43:
|
||||
return new ActionInitObject();
|
||||
case 0x53:
|
||||
return new ActionNewMethod();
|
||||
case 0x40:
|
||||
return new ActionNewObject();
|
||||
case 0x4F:
|
||||
return new ActionSetMember();
|
||||
case 0x45:
|
||||
return new ActionTargetPath();
|
||||
case 0x94:
|
||||
return new ActionWith(actionLength, this, rri, version);
|
||||
case 0x4A:
|
||||
return new ActionToNumber();
|
||||
case 0x4B:
|
||||
return new ActionToString();
|
||||
case 0x44:
|
||||
return new ActionTypeOf();
|
||||
case 0x47:
|
||||
return new ActionAdd2();
|
||||
case 0x48:
|
||||
return new ActionLess2();
|
||||
case 0x3F:
|
||||
return new ActionModulo();
|
||||
case 0x60:
|
||||
return new ActionBitAnd();
|
||||
case 0x63:
|
||||
return new ActionBitLShift();
|
||||
case 0x61:
|
||||
return new ActionBitOr();
|
||||
case 0x64:
|
||||
return new ActionBitRShift();
|
||||
case 0x65:
|
||||
return new ActionBitURShift();
|
||||
case 0x62:
|
||||
return new ActionBitXor();
|
||||
case 0x51:
|
||||
return new ActionDecrement();
|
||||
case 0x50:
|
||||
return new ActionIncrement();
|
||||
case 0x4C:
|
||||
return new ActionPushDuplicate();
|
||||
case 0x3E:
|
||||
return new ActionReturn();
|
||||
case 0x4D:
|
||||
return new ActionStackSwap();
|
||||
case 0x87:
|
||||
return new ActionStoreRegister(actionLength, this);
|
||||
//SWF6 Actions
|
||||
case 0x54:
|
||||
return new ActionInstanceOf();
|
||||
case 0x55:
|
||||
return new ActionEnumerate2();
|
||||
case 0x66:
|
||||
return new ActionStrictEquals();
|
||||
case 0x67:
|
||||
return new ActionGreater();
|
||||
case 0x68:
|
||||
return new ActionStringGreater();
|
||||
//SWF7 Actions
|
||||
case 0x8E:
|
||||
return new ActionDefineFunction2(actionLength, this, rri, version);
|
||||
case 0x69:
|
||||
return new ActionExtends();
|
||||
case 0x2B:
|
||||
return new ActionCastOp();
|
||||
case 0x2C:
|
||||
return new ActionImplementsOp();
|
||||
case 0x8F:
|
||||
return new ActionTry(actionLength, this, rri, version);
|
||||
case 0x2A:
|
||||
return new ActionThrow();
|
||||
default:
|
||||
/*if (actionLength > 0) {
|
||||
//skip(actionLength);
|
||||
}*/
|
||||
//throw new UnknownActionException(actionCode);
|
||||
Action r = new ActionNop();
|
||||
r.actionCode = actionCode;
|
||||
r.actionLength = actionLength;
|
||||
return r;
|
||||
//return new Action(actionCode, actionLength);
|
||||
}
|
||||
} catch (EndOfStreamException | ArrayIndexOutOfBoundsException eos) {
|
||||
try {
|
||||
actionCode = readUI8();
|
||||
if (actionCode == 0) {
|
||||
return new ActionEnd();
|
||||
}
|
||||
if (actionCode == -1) {
|
||||
return null;
|
||||
}
|
||||
int actionLength = 0;
|
||||
if (actionCode >= 0x80) {
|
||||
actionLength = readUI16();
|
||||
}
|
||||
switch (actionCode) {
|
||||
//SWF3 Actions
|
||||
case 0x81:
|
||||
return new ActionGotoFrame(actionLength, this);
|
||||
case 0x83:
|
||||
return new ActionGetURL(actionLength, this, version);
|
||||
case 0x04:
|
||||
return new ActionNextFrame();
|
||||
case 0x05:
|
||||
return new ActionPrevFrame();
|
||||
case 0x06:
|
||||
return new ActionPlay();
|
||||
case 0x07:
|
||||
return new ActionStop();
|
||||
case 0x08:
|
||||
return new ActionToggleQuality();
|
||||
case 0x09:
|
||||
return new ActionStopSounds();
|
||||
case 0x8A:
|
||||
return new ActionWaitForFrame(actionLength, this, cpool);
|
||||
case 0x8B:
|
||||
return new ActionSetTarget(actionLength, this, version);
|
||||
case 0x8C:
|
||||
return new ActionGoToLabel(actionLength, this, version);
|
||||
//SWF4 Actions
|
||||
case 0x96:
|
||||
return new ActionPush(actionLength, this, version);
|
||||
case 0x17:
|
||||
return new ActionPop();
|
||||
case 0x0A:
|
||||
return new ActionAdd();
|
||||
case 0x0B:
|
||||
return new ActionSubtract();
|
||||
case 0x0C:
|
||||
return new ActionMultiply();
|
||||
case 0x0D:
|
||||
return new ActionDivide();
|
||||
case 0x0E:
|
||||
return new ActionEquals();
|
||||
case 0x0F:
|
||||
return new ActionLess();
|
||||
case 0x10:
|
||||
return new ActionAnd();
|
||||
case 0x11:
|
||||
return new ActionOr();
|
||||
case 0x12:
|
||||
return new ActionNot();
|
||||
case 0x13:
|
||||
return new ActionStringEquals();
|
||||
case 0x14:
|
||||
return new ActionStringLength();
|
||||
case 0x21:
|
||||
return new ActionStringAdd();
|
||||
case 0x15:
|
||||
return new ActionStringExtract();
|
||||
case 0x29:
|
||||
return new ActionStringLess();
|
||||
case 0x31:
|
||||
return new ActionMBStringLength();
|
||||
case 0x35:
|
||||
return new ActionMBStringExtract();
|
||||
case 0x18:
|
||||
return new ActionToInteger();
|
||||
case 0x32:
|
||||
return new ActionCharToAscii();
|
||||
case 0x33:
|
||||
return new ActionAsciiToChar();
|
||||
case 0x36:
|
||||
return new ActionMBCharToAscii();
|
||||
case 0x37:
|
||||
return new ActionMBAsciiToChar();
|
||||
case 0x99:
|
||||
return new ActionJump(actionLength, this);
|
||||
case 0x9D:
|
||||
return new ActionIf(actionLength, this);
|
||||
case 0x9E:
|
||||
return new ActionCall(actionLength);
|
||||
case 0x1C:
|
||||
return new ActionGetVariable();
|
||||
case 0x1D:
|
||||
return new ActionSetVariable();
|
||||
case 0x9A:
|
||||
return new ActionGetURL2(actionLength, this);
|
||||
case 0x9F:
|
||||
return new ActionGotoFrame2(actionLength, this);
|
||||
case 0x20:
|
||||
return new ActionSetTarget2();
|
||||
case 0x22:
|
||||
return new ActionGetProperty();
|
||||
case 0x23:
|
||||
return new ActionSetProperty();
|
||||
case 0x24:
|
||||
return new ActionCloneSprite();
|
||||
case 0x25:
|
||||
return new ActionRemoveSprite();
|
||||
case 0x27:
|
||||
return new ActionStartDrag();
|
||||
case 0x28:
|
||||
return new ActionEndDrag();
|
||||
case 0x8D:
|
||||
return new ActionWaitForFrame2(actionLength, this, cpool);
|
||||
case 0x26:
|
||||
return new ActionTrace();
|
||||
case 0x34:
|
||||
return new ActionGetTime();
|
||||
case 0x30:
|
||||
return new ActionRandomNumber();
|
||||
//SWF5 Actions
|
||||
case 0x3D:
|
||||
return new ActionCallFunction();
|
||||
case 0x52:
|
||||
return new ActionCallMethod();
|
||||
case 0x88:
|
||||
return new ActionConstantPool(actionLength, this, version);
|
||||
case 0x9B:
|
||||
return new ActionDefineFunction(actionLength, this, version);
|
||||
case 0x3C:
|
||||
return new ActionDefineLocal();
|
||||
case 0x41:
|
||||
return new ActionDefineLocal2();
|
||||
case 0x3A:
|
||||
return new ActionDelete();
|
||||
case 0x3B:
|
||||
return new ActionDelete2();
|
||||
case 0x46:
|
||||
return new ActionEnumerate();
|
||||
case 0x49:
|
||||
return new ActionEquals2();
|
||||
case 0x4E:
|
||||
return new ActionGetMember();
|
||||
case 0x42:
|
||||
return new ActionInitArray();
|
||||
case 0x43:
|
||||
return new ActionInitObject();
|
||||
case 0x53:
|
||||
return new ActionNewMethod();
|
||||
case 0x40:
|
||||
return new ActionNewObject();
|
||||
case 0x4F:
|
||||
return new ActionSetMember();
|
||||
case 0x45:
|
||||
return new ActionTargetPath();
|
||||
case 0x94:
|
||||
return new ActionWith(actionLength, this, version);
|
||||
case 0x4A:
|
||||
return new ActionToNumber();
|
||||
case 0x4B:
|
||||
return new ActionToString();
|
||||
case 0x44:
|
||||
return new ActionTypeOf();
|
||||
case 0x47:
|
||||
return new ActionAdd2();
|
||||
case 0x48:
|
||||
return new ActionLess2();
|
||||
case 0x3F:
|
||||
return new ActionModulo();
|
||||
case 0x60:
|
||||
return new ActionBitAnd();
|
||||
case 0x63:
|
||||
return new ActionBitLShift();
|
||||
case 0x61:
|
||||
return new ActionBitOr();
|
||||
case 0x64:
|
||||
return new ActionBitRShift();
|
||||
case 0x65:
|
||||
return new ActionBitURShift();
|
||||
case 0x62:
|
||||
return new ActionBitXor();
|
||||
case 0x51:
|
||||
return new ActionDecrement();
|
||||
case 0x50:
|
||||
return new ActionIncrement();
|
||||
case 0x4C:
|
||||
return new ActionPushDuplicate();
|
||||
case 0x3E:
|
||||
return new ActionReturn();
|
||||
case 0x4D:
|
||||
return new ActionStackSwap();
|
||||
case 0x87:
|
||||
return new ActionStoreRegister(actionLength, this);
|
||||
//SWF6 Actions
|
||||
case 0x54:
|
||||
return new ActionInstanceOf();
|
||||
case 0x55:
|
||||
return new ActionEnumerate2();
|
||||
case 0x66:
|
||||
return new ActionStrictEquals();
|
||||
case 0x67:
|
||||
return new ActionGreater();
|
||||
case 0x68:
|
||||
return new ActionStringGreater();
|
||||
//SWF7 Actions
|
||||
case 0x8E:
|
||||
return new ActionDefineFunction2(actionLength, this, version);
|
||||
case 0x69:
|
||||
return new ActionExtends();
|
||||
case 0x2B:
|
||||
return new ActionCastOp();
|
||||
case 0x2C:
|
||||
return new ActionImplementsOp();
|
||||
case 0x8F:
|
||||
return new ActionTry(actionLength, this, version);
|
||||
case 0x2A:
|
||||
return new ActionThrow();
|
||||
default:
|
||||
/*if (actionLength > 0) {
|
||||
//skip(actionLength);
|
||||
}*/
|
||||
//throw new UnknownActionException(actionCode);
|
||||
Action r = new ActionNop();
|
||||
r.actionCode = actionCode;
|
||||
r.actionLength = actionLength;
|
||||
return r;
|
||||
//return new Action(actionCode, actionLength);
|
||||
}
|
||||
} catch (EndOfStreamException | ArrayIndexOutOfBoundsException eos) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.NotCompileTimeItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -71,7 +71,7 @@ public class ActionListReader {
|
||||
* ActionEndFlag(=0) or end of the stream.
|
||||
* @param listeners
|
||||
* @param containerSWFOffset
|
||||
* @param rri
|
||||
* @param mis
|
||||
* @param version
|
||||
* @param ip
|
||||
* @param endIp
|
||||
@@ -79,19 +79,18 @@ public class ActionListReader {
|
||||
* @return List of actions
|
||||
* @throws IOException
|
||||
*/
|
||||
public static List<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endIp, String path) throws IOException {
|
||||
public static List<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, MemoryInputStream mis, int version, int ip, int endIp, String path) throws IOException {
|
||||
boolean deobfuscate = Configuration.autoDeobfuscate.get();
|
||||
|
||||
ConstantPool cpool = new ConstantPool();
|
||||
|
||||
SWFInputStream sis = new SWFInputStream(rri, version);
|
||||
SWFInputStream sis = new SWFInputStream(mis, version);
|
||||
|
||||
// List of the actions. N. item contains the action which starts in offset N.
|
||||
List<Action> actionMap = new ArrayList<>();
|
||||
List<Long> nextOffsets = new ArrayList<>();
|
||||
Action entryAction = readActionListAtPos(listeners, containerSWFOffset, cpool,
|
||||
sis, rri,
|
||||
actionMap, nextOffsets,
|
||||
Action entryAction = readActionListAtPos(listeners, containerSWFOffset, cpool,
|
||||
sis, actionMap, nextOffsets,
|
||||
ip, ip, endIp, version, path, false, new ArrayList<Long>());
|
||||
|
||||
Map<Action, List<Action>> containerLastActions = new HashMap<>();
|
||||
@@ -534,8 +533,7 @@ public class ActionListReader {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Action readActionListAtPos(List<DisassemblyListener> listeners, long containerSWFOffset, ConstantPool cpool,
|
||||
SWFInputStream sis, ReReadableInputStream rri,
|
||||
List<Action> actions, List<Long> nextOffsets,
|
||||
SWFInputStream sis, List<Action> actions, List<Long> nextOffsets,
|
||||
long ip, long startIp, long endIp, int version, String path, boolean indeterminate, List<Long> visitedContainers) throws IOException {
|
||||
|
||||
Action entryAction = null;
|
||||
@@ -550,10 +548,10 @@ public class ActionListReader {
|
||||
while (!jumpQueue.isEmpty()) {
|
||||
ip = jumpQueue.remove();
|
||||
while ((endIp == -1) || (endIp > ip)) {
|
||||
rri.setPos((int) ip);
|
||||
sis.seek((int) ip);
|
||||
|
||||
Action a;
|
||||
if ((a = sis.readAction(rri, cpool)) == null) {
|
||||
if ((a = sis.readAction(cpool)) == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -583,8 +581,10 @@ public class ActionListReader {
|
||||
actions.set((int) ip, a);
|
||||
nextOffsets.set((int) ip, ip + actionLengthWithHeader);
|
||||
|
||||
long pos = sis.getPos();
|
||||
long length = pos + sis.available();
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
listeners.get(i).progress("Reading", rri.getCount(), rri.length());
|
||||
listeners.get(i).progress("Reading", pos, length);
|
||||
}
|
||||
|
||||
a.containerSWFOffset = containerSWFOffset;
|
||||
@@ -619,8 +619,7 @@ public class ActionListReader {
|
||||
long ip2 = ip + actionLengthWithHeader;
|
||||
//long endIp2 = ip + actionLengthWithHeader + size;
|
||||
readActionListAtPos(listeners, containerSWFOffset, cpool,
|
||||
sis, rri,
|
||||
actions, nextOffsets,
|
||||
sis, actions, nextOffsets,
|
||||
ip2, startIp, endIp, version, newPath, indeterminate, visitedContainers);
|
||||
actionLengthWithHeader += size;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -56,7 +55,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta
|
||||
this.paramNames = paramNames;
|
||||
}
|
||||
|
||||
public ActionDefineFunction(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException {
|
||||
public ActionDefineFunction(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x9B, actionLength);
|
||||
this.version = version;
|
||||
//byte[] data=sis.readBytes(actionLength);
|
||||
@@ -71,7 +70,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta
|
||||
long endPos = sis.getPos();
|
||||
//code = new ArrayList<Action>();
|
||||
hdrSize = endPos - startPos;
|
||||
int posBef2 = (int) rri.getPos();
|
||||
//int posBef2 = (int) rri.getPos();
|
||||
//code = sis.readActionList(rri.getPos(), getFileAddress() + hdrSize, rri, codeSize);
|
||||
//rri.setPos(posBef2 + codeSize);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.jpexs.decompiler.graph.ExportMode;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -50,7 +49,7 @@ public class ActionWith extends Action implements GraphSourceItemContainer {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ActionWith(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException {
|
||||
public ActionWith(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x94, actionLength);
|
||||
codeSize = sis.readUI16();
|
||||
this.version = version;
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -78,7 +77,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont
|
||||
this.paramRegisters = paramRegisters;
|
||||
}
|
||||
|
||||
public ActionDefineFunction2(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException {
|
||||
public ActionDefineFunction2(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x8E, actionLength);
|
||||
long posBef = sis.getPos();
|
||||
this.version = version;
|
||||
@@ -103,7 +102,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont
|
||||
long posAfter = sis.getPos();
|
||||
hdrSize = posAfter - posBef;
|
||||
//code = new ArrayList<Action>();
|
||||
int posBef2 = (int) rri.getPos();
|
||||
//int posBef2 = (int) rri.getPos();
|
||||
//code = sis.readActionList(rri.getPos(), getFileAddress() + hdrSize, rri, codeSize);
|
||||
//rri.setPos(posBef2 + codeSize);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -64,7 +63,7 @@ public class ActionTry extends Action implements GraphSourceItemContainer {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public ActionTry(int actionLength, SWFInputStream sis, ReReadableInputStream rri, int version) throws IOException {
|
||||
public ActionTry(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x8F, actionLength);
|
||||
long startPos = sis.getPos();
|
||||
sis.readUB(5);
|
||||
|
||||
@@ -104,7 +104,7 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
|
||||
ReReadableInputStream is = new ReReadableInputStream(pmi);
|
||||
SWF swf = new SWF(is, null, false, true);
|
||||
long limit = pmi.getPos();
|
||||
is.setPos(0);
|
||||
is.seek(0);
|
||||
is = new ReReadableInputStream(new LimitedInputStream(is, limit));
|
||||
if (swf.fileSize > 0 && swf.version > 0 && !swf.tags.isEmpty() && swf.version < 25/*Needs to be fixed when SWF versions reaches this value*/) {
|
||||
String p = translate("swfitem").replace("%version%", "" + swf.version).replace("%size%", "" + swf.fileSize);
|
||||
@@ -143,7 +143,7 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
|
||||
if (index > -1) {
|
||||
ReReadableInputStream str = foundIs.get(index);
|
||||
try {
|
||||
str.setPos(0);
|
||||
str.seek(0);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(LoadFromMemoryFrame.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return;
|
||||
@@ -362,12 +362,12 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
|
||||
try {
|
||||
if (selected.length == 1) {
|
||||
ReReadableInputStream bis = foundIs.get(selected[0]);
|
||||
bis.setPos(0);
|
||||
bis.seek(0);
|
||||
Helper.saveStream(bis, file);
|
||||
} else {
|
||||
for (int sel : selected) {
|
||||
ReReadableInputStream bis = foundIs.get(sel);
|
||||
bis.setPos(0);
|
||||
bis.seek(0);
|
||||
Helper.saveStream(bis, new File(file, "movie" + sel + ".swf"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ProgressListener;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.helpers.streams.SeekableInputStream;
|
||||
import com.jpexs.helpers.utf8.Utf8PrintWriter;
|
||||
import com.sun.jna.Platform;
|
||||
import java.awt.*;
|
||||
@@ -313,9 +313,9 @@ public class Main {
|
||||
} else {
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
openFile(file);
|
||||
} else if (inputStream instanceof ReReadableInputStream) {
|
||||
} else if (inputStream instanceof SeekableInputStream) {
|
||||
try {
|
||||
((ReReadableInputStream) inputStream).setPos(0);
|
||||
((SeekableInputStream) inputStream).seek(0);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,6 @@ import com.jpexs.helpers.AsyncResult;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Callback;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Stopwatch;
|
||||
import com.jpexs.process.ProcessTools;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
@@ -3154,7 +3153,7 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T
|
||||
try {
|
||||
tempFile = File.createTempFile("temp", ".swf");
|
||||
tempFile.deleteOnExit();
|
||||
swf.saveTo(new FileOutputStream(tempFile));
|
||||
swf.saveTo(new BufferedOutputStream(new FileOutputStream(tempFile)));
|
||||
flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, swf.frameRate);
|
||||
} catch (IOException iex) {
|
||||
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Cannot create tempfile", iex);
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.graph.ExportMode;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.awt.Color;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -173,8 +173,8 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
|
||||
prevLength = prevData.length;
|
||||
}
|
||||
baos.write(actionBytes);
|
||||
ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
rri.setPos(prevLength);
|
||||
MemoryInputStream rri = new MemoryInputStream(baos.toByteArray());
|
||||
rri.seek(prevLength);
|
||||
|
||||
List<Action> list = ActionListReader.readActionList(listeners, getPos() + hdrSize - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/);
|
||||
return list;
|
||||
|
||||
@@ -25,8 +25,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.graph.ExportMode;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -118,8 +117,8 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
prevLength += header.length;
|
||||
}
|
||||
baos.write(actionBytes);
|
||||
ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
rri.setPos(prevLength);
|
||||
MemoryInputStream rri = new MemoryInputStream(baos.toByteArray());
|
||||
rri.seek(prevLength);
|
||||
List<Action> list = ActionListReader.readActionList(listeners, getPos() - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.graph.ExportMode;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -127,8 +127,8 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource {
|
||||
prevLength += header.length;
|
||||
}
|
||||
baos.write(actionBytes);
|
||||
ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
rri.setPos(prevLength);
|
||||
MemoryInputStream rri = new MemoryInputStream(baos.toByteArray());
|
||||
rri.seek(prevLength);
|
||||
List<Action> list = ActionListReader.readActionList(listeners, getPos() + 2 - prevLength, rri, version, prevLength, -1, toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -27,8 +27,7 @@ import com.jpexs.decompiler.flash.tags.base.ContainerItem;
|
||||
import com.jpexs.decompiler.flash.tags.base.Exportable;
|
||||
import com.jpexs.decompiler.graph.ExportMode;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -175,7 +174,7 @@ public class BUTTONCONDACTION implements ASMSource, Exportable, ContainerItem {
|
||||
@Override
|
||||
public List<Action> getActions(int version) {
|
||||
try {
|
||||
List<Action> list = ActionListReader.readActionList(listeners, getPos() + 4, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1, toString()/*FIXME?*/);
|
||||
List<Action> list = ActionListReader.readActionList(listeners, getPos() + 4, new MemoryInputStream(actionBytes), version, 0, -1, toString()/*FIXME?*/);
|
||||
return list;
|
||||
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -27,8 +27,7 @@ import com.jpexs.decompiler.flash.tags.base.ContainerItem;
|
||||
import com.jpexs.decompiler.flash.tags.base.Exportable;
|
||||
import com.jpexs.decompiler.graph.ExportMode;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -174,7 +173,7 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem {
|
||||
@Override
|
||||
public List<Action> getActions(int version) {
|
||||
try {
|
||||
List<Action> list = ActionListReader.readActionList(listeners, getPos() + hdrPos, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1, toString()/*FIXME?*/);
|
||||
List<Action> list = ActionListReader.readActionList(listeners, getPos() + hdrPos, new MemoryInputStream(actionBytes), version, 0, -1, toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class GFxInputStream extends InputStream {
|
||||
}
|
||||
|
||||
public void setPos(long pos) throws IOException {
|
||||
is.setPos(pos);
|
||||
is.seek(pos);
|
||||
}
|
||||
|
||||
public long getPos() {
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.helpers;
|
||||
|
||||
import com.jpexs.helpers.streams.SeekableInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MemoryInputStream extends SeekableInputStream {
|
||||
|
||||
byte[] buffer;
|
||||
long pos = 0;
|
||||
int count = 0;
|
||||
|
||||
public MemoryInputStream(byte[] buffer) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public byte[] getAllRead() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public long getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long pos) throws IOException {
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (pos > count) {
|
||||
count = (int) pos;
|
||||
}
|
||||
|
||||
if (pos < buffer.length) {
|
||||
int ret = buffer[(int) pos] & 0xff;
|
||||
pos++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return buffer.length - (int) pos;
|
||||
}
|
||||
|
||||
public long length() throws IOException {
|
||||
return buffer.length;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.helpers;
|
||||
|
||||
import com.jpexs.helpers.streams.SeekableInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -24,7 +25,7 @@ import java.io.InputStream;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ReReadableInputStream extends InputStream {
|
||||
public class ReReadableInputStream extends SeekableInputStream {
|
||||
|
||||
InputStream is;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
@@ -48,7 +49,8 @@ public class ReReadableInputStream extends InputStream {
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
public void setPos(long pos) throws IOException {
|
||||
@Override
|
||||
public void seek(long pos) throws IOException {
|
||||
if (pos > count) {
|
||||
this.pos = count;
|
||||
skip(pos - count);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.helpers.streams;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class SeekableInputStream extends InputStream {
|
||||
|
||||
public abstract void seek(long pos) throws IOException;
|
||||
}
|
||||
Reference in New Issue
Block a user