mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-06 20:08:15 +00:00
as3 execution fixes
This commit is contained in:
@@ -16,18 +16,16 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Runtime;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2RuntimeInfo;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.exceptions.AVM2ExecutionException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.IfTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionLocalData;
|
||||
import com.jpexs.decompiler.flash.action.LocalDataArea;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionAdd;
|
||||
@@ -74,33 +72,20 @@ import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.ecma.Undefined;
|
||||
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.javactivex.ActiveX;
|
||||
import com.jpexs.javactivex.ActiveXEvent;
|
||||
import com.jpexs.javactivex.ActiveXEventListener;
|
||||
import com.jpexs.javactivex.Reference;
|
||||
import com.jpexs.javactivex.example.controls.flash.ShockwaveFlash;
|
||||
import java.awt.Panel;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import org.testng.Assert;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -108,70 +93,67 @@ import static org.testng.Assert.fail;
|
||||
*/
|
||||
public class FlashPlayerTest {
|
||||
|
||||
private final Object lockObj = new Object();
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
private final AVM2RuntimeInfo adobeRuntime = new AVM2RuntimeInfo(AVM2Runtime.ADOBE_FLASH, 19, false);
|
||||
|
||||
//@Test
|
||||
public void test1() throws IOException, InterruptedException {
|
||||
final Reference<String> resultRef = new Reference<>(null);
|
||||
public void testAs3Pushes() throws IOException, InterruptedException {
|
||||
AdobeFlashExecutor adobeExecutor = new AdobeFlashExecutor();
|
||||
|
||||
ShockwaveFlash flash = ActiveX.createObject(ShockwaveFlash.class, new Panel());
|
||||
flash.setAllowScriptAccess("always");
|
||||
flash.setAllowNetworking("all");
|
||||
flash.addFSCommandListener(new ActiveXEventListener() {
|
||||
adobeExecutor.loadTestSwf();
|
||||
ABC abc = adobeExecutor.as3TestSwfAbcTag.getABC();
|
||||
abc.constants.ensureStringCapacity(1000000);
|
||||
abc.constants.ensureMultinameCapacity(1000000);
|
||||
AVM2Instruction[] pushes = getAs3Pushes(abc);
|
||||
|
||||
@Override
|
||||
public void onEvent(ActiveXEvent axe) {
|
||||
resultRef.setVal((String) axe.args.get("args"));
|
||||
synchronized (lockObj) {
|
||||
lockObj.notify();
|
||||
}
|
||||
List<AS3ExecuteTask> tasks = new ArrayList<>();
|
||||
for (int p1 = 0; p1 < pushes.length; p1++) {
|
||||
AVM2Code ccode = new AVM2Code();
|
||||
ccode.code = new ArrayList<>();
|
||||
List<AVM2Instruction> code = ccode.code;
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.GetLocal0, null));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.PushScope, null));
|
||||
code.add(pushes[p1].clone());
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.ReturnValue, null));
|
||||
ccode.markOffsets();
|
||||
|
||||
AS3ExecuteTask task = new AS3ExecuteTask();
|
||||
task.description = p1 + ", " + pushes[p1].definition.instructionName;
|
||||
task.code = ccode;
|
||||
|
||||
String ffdecExecuteResult;
|
||||
try {
|
||||
Object res = ccode.execute(new HashMap<>(), abc.constants, adobeRuntime);
|
||||
ffdecExecuteResult = "Result:" + EcmaScript.toString(res) + " Type:" + EcmaScript.typeString(res);
|
||||
} catch (AVM2ExecutionException ex) {
|
||||
ffdecExecuteResult = "Error:" + ex.getMessage();
|
||||
}
|
||||
});
|
||||
|
||||
File f = new File("libsrc/ffdec_lib/testdata/run_as3/run.swf");
|
||||
|
||||
SWF swf = new SWF(new BufferedInputStream(new FileInputStream(f)), false);
|
||||
swf.version = SWF.MAX_VERSION;
|
||||
DoABC2Tag abcTag = null;
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof DoABC2Tag) {
|
||||
abcTag = ((DoABC2Tag) t);
|
||||
break;
|
||||
}
|
||||
task.ffdecResult = ffdecExecuteResult;
|
||||
tasks.add(task);
|
||||
}
|
||||
|
||||
ABC abc = abcTag.getABC();
|
||||
abc.constants.addUInt(0);
|
||||
abc.constants.addUInt(100);
|
||||
abc.constants.addDouble(0.0);
|
||||
abc.constants.addDouble(111.11);
|
||||
MethodBody body = abc.findBodyByClassAndName("Run", "run");
|
||||
body.max_stack = 20;
|
||||
body.max_regs = 10;
|
||||
adobeExecutor.executeAvm2(tasks);
|
||||
for (AS3ExecuteTask task : tasks) {
|
||||
System.out.println("Flash result (" + task.description + "): " + task.flashResult);
|
||||
System.out.println("FFDec execte result: " + task.ffdecResult);
|
||||
assertEquals(task.ffdecResult, task.flashResult);
|
||||
}
|
||||
}
|
||||
|
||||
AVM2Instruction[] pushes = new AVM2Instruction[]{
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUndefined, null),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushNull, null),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushTrue, null),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushFalse, null),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushNan, null),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{1}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{1}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{1}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{1}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{1}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-2}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-1}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{0}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{1}),
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{2}),};
|
||||
@Test
|
||||
public void testAs3() throws IOException, InterruptedException {
|
||||
AdobeFlashExecutor adobeExecutor = new AdobeFlashExecutor();
|
||||
|
||||
for (int i = 58; i < 256; i++) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
System.out.println("Instruction code: " + Integer.toHexString(i) + " (" + i + ")");
|
||||
List<AS3ExecuteTask> tasks = new ArrayList<>();
|
||||
adobeExecutor.loadTestSwf();
|
||||
ABC abc = adobeExecutor.as3TestSwfAbcTag.getABC();
|
||||
AVM2Instruction[] pushes = getAs3Pushes(abc);
|
||||
for (int p1 = 0; p1 < pushes.length; p1++) {
|
||||
for (int p2 = 0; p2 < pushes.length; p2++) {
|
||||
System.out.println("p1: " + p1 + " p2: " + p2);
|
||||
// todo: the following instructions are not implemented
|
||||
if (i == AVM2Instructions.GetSuper
|
||||
|| i == AVM2Instructions.SetSuper
|
||||
@@ -231,11 +213,6 @@ public class FlashPlayerTest {
|
||||
continue;
|
||||
}
|
||||
|
||||
System.out.println("Instruction code: " + Integer.toHexString(i) + " (" + i + ") " + AVM2Code.instructionSet[i].instructionName);
|
||||
int j = 1;
|
||||
File f2 = new File("run_test_" + new Date().getTime() + "_" + i + "_" + j + ".swf");
|
||||
f2.deleteOnExit();
|
||||
|
||||
AVM2Code ccode = new AVM2Code();
|
||||
ccode.code = new ArrayList<>();
|
||||
List<AVM2Instruction> code = ccode.code;
|
||||
@@ -276,225 +253,349 @@ public class FlashPlayerTest {
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.TypeOf, null));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.Add, null));
|
||||
code.add(new AVM2Instruction(0, AVM2Instructions.ReturnValue, null));
|
||||
ccode.markOffsets();
|
||||
|
||||
body.setCode(ccode);
|
||||
body.markOffsets();
|
||||
//String pcode = ccode.toASMSource();
|
||||
//String as = body.toSource();
|
||||
|
||||
abcTag.setModified(true);
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f2))) {
|
||||
swf.saveTo(fos);
|
||||
}
|
||||
|
||||
flash.setMovie(f2.getAbsolutePath());
|
||||
|
||||
synchronized (lockObj) {
|
||||
lockObj.wait();
|
||||
}
|
||||
|
||||
f2.delete();
|
||||
|
||||
String flashResult = resultRef.getVal();
|
||||
System.out.println("Flash result: " + flashResult);
|
||||
AS3ExecuteTask task = new AS3ExecuteTask();
|
||||
task.description = "Instruction code: " + Integer.toHexString(i) + " (" + i + ") " + AVM2Code.instructionSet[i].instructionName + ", "
|
||||
+ "p1: " + p1 + ", " + pushes[p1].definition.instructionName + ", "
|
||||
+ "p2: " + p2 + ", " + pushes[p2].definition.instructionName;
|
||||
task.code = ccode;
|
||||
|
||||
String ffdecExecuteResult;
|
||||
try {
|
||||
Object res = ccode.execute(new HashMap<>(), abc.constants, AVM2Runtime.ADOBE_FLASH, 19);
|
||||
Object res = ccode.execute(new HashMap<>(), abc.constants, adobeRuntime);
|
||||
ffdecExecuteResult = "Result:" + EcmaScript.toString(res) + " Type:" + EcmaScript.typeString(res);
|
||||
} catch (AVM2ExecutionException ex) {
|
||||
ffdecExecuteResult = "Error:" + ex.getMessage();
|
||||
}
|
||||
|
||||
System.out.println("FFDec execte result: " + ffdecExecuteResult);
|
||||
task.ffdecResult = ffdecExecuteResult;
|
||||
tasks.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals(ffdecExecuteResult, flashResult);
|
||||
adobeExecutor.executeAvm2(tasks);
|
||||
|
||||
StringBuilder expeced = new StringBuilder();
|
||||
StringBuilder current = new StringBuilder();
|
||||
for (AS3ExecuteTask task : tasks) {
|
||||
/*System.out.println("Flash result (" + task.description + "): " + task.flashResult);
|
||||
System.out.println("FFDec execte result: " + task.ffdecResult);
|
||||
|
||||
if (!task.ffdecResult.equals(task.flashResult)) {
|
||||
String ffdecExecuteResult;
|
||||
try {
|
||||
Object res = task.code.execute(new HashMap<>(), abc.constants, adobeRuntime);
|
||||
ffdecExecuteResult = "Result:" + EcmaScript.toString(res) + " Type:" + EcmaScript.typeString(res);
|
||||
} catch (AVM2ExecutionException ex) {
|
||||
ffdecExecuteResult = "Error:" + ex.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(task.ffdecResult, task.flashResult);*/
|
||||
expeced.append(task.flashResult).append(Helper.newLine);
|
||||
current.append(task.ffdecResult).append(Helper.newLine);
|
||||
}
|
||||
|
||||
Helper.writeFile("c:\\1\\expected\\" + i + ".txt", Utf8Helper.getBytes(expeced.toString()));
|
||||
Helper.writeFile("c:\\1\\current\\" + i + ".txt", Utf8Helper.getBytes(current.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private AVM2Instruction[] getAs3Pushes(ABC abc) {
|
||||
AVM2Instruction[] pushes = new AVM2Instruction[]{
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUndefined, null), // 0
|
||||
new AVM2Instruction(0, AVM2Instructions.PushNull, null), // 1
|
||||
new AVM2Instruction(0, AVM2Instructions.PushTrue, null), // 2
|
||||
new AVM2Instruction(0, AVM2Instructions.PushFalse, null), // 3
|
||||
new AVM2Instruction(0, AVM2Instructions.PushNan, null), // 4
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{0}), // 5
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("", true)}), // 6
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("-2147483649", true)}), // 7
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("-2147483648", true)}), // 8
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("-2147483647", true)}), // 9
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("-1", true)}), // 10
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("0", true)}), // 11
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("1", true)}), // 12
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("2147483647", true)}), // 13
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("2147483648", true)}), // 14
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("4294967295", true)}), // 15
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("4294967296", true)}), // 16
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("1test", true)}), // 17
|
||||
new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{abc.constants.getStringId("test", true)}), // 18
|
||||
new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{0}), // 19
|
||||
new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{abc.constants.getDoubleId(-1, true)}), // 20
|
||||
new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{abc.constants.getDoubleId(-0.5, true)}), // 21
|
||||
new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{abc.constants.getDoubleId(0, true)}), // 22
|
||||
new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{abc.constants.getDoubleId(0.5, true)}), // 23
|
||||
new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{abc.constants.getDoubleId(1, true)}), // 24
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-2147483648}), // 25
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-2147483647}), // 26
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-1073741824}), // 27
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-1073741823}), // 28
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-536870912}), // 29
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-536870911}), // 30
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-268435456}), // 31
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-134217728}), // 32
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-134217727}), // 33
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-67108864}), // 34
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-67108863}), // 35
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-33554432}), // 36
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-33554431}), // 37
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-16777216}), // 38
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-16777215}), // 39
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-8388608}), // 40
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-8388607}), // 41
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-4194304}), // 42
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-4194303}), // 43
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-2097152}), // 44
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-2097151}), // 45
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-1048576}), // 46
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-1048575}), // 47
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-524288}), // 48
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-524287}), // 49
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-262144}), // 50
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-262143}), // 51
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-131072}), // 52
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-131071}), // 53
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-65536}), // 54
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-65535}), // 55
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-32768}), // 56
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-32767}), // 57
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{-1}), // 58
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{0}), // 59
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{1}), // 60
|
||||
/*new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{127}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{128}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{255}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{256}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{511}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{512}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{1023}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{1024}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{2047}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{2048}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{4095}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{4096}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{8191}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{8192}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{16383}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{16384}), // 62*/
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{32767}), // 61
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{32768}), // 62
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{268435455}), // 63
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{268435456}), // 64
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{536870911}), // 65
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{536870912}), // 66
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{1073741823}), // 67
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{1073741824}), // 68
|
||||
new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{2147483647}), // 69
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{0}), // 70
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{abc.constants.getIntId(-2147483649L, true)}), // 71
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{abc.constants.getIntId(-2147483648, true)}), // 72
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{abc.constants.getIntId(-1, true)}), // 73
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{abc.constants.getIntId(0, true)}), // 74
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{abc.constants.getIntId(1, true)}), // 75
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{abc.constants.getIntId(2147483647, true)}), // 76
|
||||
new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{abc.constants.getIntId(2147483648L, true)}), // 77
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getIntId(4294967295L, true)}), // 78
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getIntId(4294967296L, true)}), // 79
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{0}), // 80
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(-2147483649L, true)}), // 81
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(-2147483648, true)}), // 82
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(-1, true)}), // 83
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(0, true)}), // 84
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(1, true)}), // 85
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(2147483647, true)}), // 86
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(2147483648L, true)}), // 87
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(4294967295L, true)}), // 88
|
||||
new AVM2Instruction(0, AVM2Instructions.PushUInt, new int[]{abc.constants.getUIntId(4294967296L, true)}), // 89
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-2147483648}), // 90
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-256}), // 91
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-255}), // 92
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-128}), // 93
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-127}), // 94
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-2}), // 95
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{-1}), // 96
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{0}), // 97
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{1}), // 98
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{2}), // 99
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{127}), // 100
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{128}), // 101
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{255}), // 102
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{256}), // 103
|
||||
new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{2147483647}),}; // 104
|
||||
return pushes;
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void testAs2() throws InterruptedException {
|
||||
AdobeFlashExecutor adobeExecutor = new AdobeFlashExecutor();
|
||||
|
||||
List<AS2ExecuteTask> tasks = new ArrayList<>();
|
||||
Object[] pushes = getAs2Pushes();
|
||||
for (int i = 0; i < 13 + 23 + 2; i++) {
|
||||
for (int p1 = 0; p1 < 15; p1++) {
|
||||
int p2Count = 1;
|
||||
if (i >= 13) {
|
||||
p2Count = pushes.length;
|
||||
}
|
||||
|
||||
for (int p2 = 0; p2 < p2Count; p2++) {
|
||||
|
||||
List<Action> newActions = new ArrayList<>();
|
||||
Action opAction = getOpAction(i);
|
||||
|
||||
if (i >= 13 + 23) {
|
||||
newActions.add(new ActionPush("mystring_árvíztűrő_tükörfúrógép"));
|
||||
}
|
||||
|
||||
Object p1o = pushes[p1];
|
||||
Object p2o = null;
|
||||
if (i >= 13) {
|
||||
p2o = pushes[p2];
|
||||
newActions.add(new ActionPush(p2o));
|
||||
}
|
||||
|
||||
newActions.add(new ActionPush(p1o));
|
||||
|
||||
newActions.add(opAction);
|
||||
newActions.add(new ActionPushDuplicate());
|
||||
newActions.add(new ActionTypeOf());
|
||||
newActions.add(new ActionStackSwap());
|
||||
newActions.add(new ActionStringAdd());
|
||||
|
||||
AS2ExecuteTask task = new AS2ExecuteTask();
|
||||
task.description = i + " " + opAction.toString() + " p1:" + p1o + " p2:" + p2o + " r3:" + "mystring";
|
||||
task.actions = newActions;
|
||||
|
||||
List<GraphTargetItem> output = new ArrayList<>();
|
||||
ActionLocalData localData = new ActionLocalData();
|
||||
TranslateStack stack = new TranslateStack("");
|
||||
for (Action a : newActions) {
|
||||
a.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
|
||||
}
|
||||
|
||||
String ffdecTranslateResult;
|
||||
try {
|
||||
Object res = stack.pop().getResult();
|
||||
ffdecTranslateResult = "Result:" + EcmaScript.toString(res) + " Type:" + EcmaScript.typeString(res);
|
||||
} catch (Exception e) {
|
||||
ffdecTranslateResult = "Error:" + e.getMessage();
|
||||
}
|
||||
|
||||
String ffdecExecuteResult;
|
||||
try {
|
||||
LocalDataArea lda = new LocalDataArea();
|
||||
for (Action a : newActions) {
|
||||
if (!a.execute(lda)) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
Object res = lda.stack.pop();
|
||||
ffdecExecuteResult = "Result:" + EcmaScript.toString(res) + " Type:" + EcmaScript.typeString(res);
|
||||
} catch (Exception e) {
|
||||
ffdecExecuteResult = "Error:" + e.getMessage();
|
||||
}
|
||||
|
||||
assertEquals(ffdecTranslateResult, ffdecExecuteResult);
|
||||
|
||||
task.ffdecResult = ffdecExecuteResult;
|
||||
tasks.add(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*int cnt = 0;
|
||||
while (flash.getReadyState() != 4) {
|
||||
Thread.sleep(50);
|
||||
if (cnt > 100) {
|
||||
Assert.fail("Flash init timeout");
|
||||
}
|
||||
adobeExecutor.executeActionLists(tasks);
|
||||
|
||||
cnt++;
|
||||
}*/
|
||||
/*try {
|
||||
String res = flash.CallFunction("<invoke name=\"testFunc\" returntype=\"xml\"><arguments><string>something</string></arguments></invoke>");
|
||||
//String str = flash.GetVariable("_root.myText.text");
|
||||
throw new Error(res + " " + body.getCode().toString() + "");
|
||||
} catch (Exception ex) {
|
||||
int a = 1;
|
||||
}*/
|
||||
}
|
||||
StringBuilder expeced = new StringBuilder();
|
||||
StringBuilder current = new StringBuilder();
|
||||
for (AS2ExecuteTask task : tasks) {
|
||||
System.out.println(task.description);
|
||||
String flashResult = task.flashResult;
|
||||
String ffdecResult = task.ffdecResult;
|
||||
System.out.println("FFDec result: " + ffdecResult);
|
||||
|
||||
//@Test
|
||||
public void testAs2() throws IOException, InterruptedException {
|
||||
final Reference<String> resultRef = new Reference<>(null);
|
||||
boolean checkOnlyStart = false;
|
||||
/*if (flashResult.length() > 10) {
|
||||
boolean onlyNumber = true;
|
||||
for (int k = 0; k < 10; k++) {
|
||||
char ch = flashResult.charAt(flashResult.length() - k - 1);
|
||||
if (ch < '0' || ch > '9') {
|
||||
onlyNumber = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ShockwaveFlash flash = ActiveX.createObject(ShockwaveFlash.class, new Panel());
|
||||
flash.setAllowScriptAccess("always");
|
||||
flash.setAllowNetworking("all");
|
||||
flash.addFSCommandListener(new ActiveXEventListener() {
|
||||
if (onlyNumber) {
|
||||
flashResult = flashResult.substring(0, flashResult.length() - 1);
|
||||
checkOnlyStart = true;
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void onEvent(ActiveXEvent axe) {
|
||||
resultRef.setVal((String) axe.args.get("args"));
|
||||
synchronized (lockObj) {
|
||||
lockObj.notify();
|
||||
}
|
||||
if (flashResult.equals("Result:number-0.00390625000090949 Type:string")) {
|
||||
flashResult = "Result:number-0.0039062500009095 Type:string";
|
||||
} else if (flashResult.equals("Result:number-0.0000610349234335671 Type:string")) {
|
||||
flashResult = "Result:number-0.0000610349234335672 Type:string";
|
||||
}
|
||||
});
|
||||
|
||||
File f = new File("libsrc/ffdec_lib/testdata/run_as2/run_as2.swf");
|
||||
for (int i = 0; i < 15; i++) {
|
||||
for (int j = 0; j < 13 + 23 + 2; j++) {
|
||||
|
||||
File f2 = new File("run_test_" + new Date().getTime() + "_" + i + "_" + j + ".swf");
|
||||
f2.deleteOnExit();
|
||||
|
||||
SWF swf = new SWF(new BufferedInputStream(new FileInputStream(f)), false);
|
||||
Map<String, ASMSource> asms = swf.getASMs(true);
|
||||
ASMSource asm = asms.get("\\frame_1\\DoAction");
|
||||
ActionList actions = asm.getActions();
|
||||
actions.removeAction(2, 4);
|
||||
|
||||
List<Action> newActions = new ArrayList<>();
|
||||
int r1 = random.nextInt(500) - 255;
|
||||
int r2 = random.nextInt(100);
|
||||
|
||||
Action opAction = getOpAction(j);
|
||||
|
||||
if (j >= 13 + 23) {
|
||||
newActions.add(new ActionPush("mystring_árvíztűrő_tükörfúrógép"));
|
||||
}
|
||||
|
||||
if (j >= 13) {
|
||||
newActions.add(new ActionPush(r1));
|
||||
}
|
||||
|
||||
Object r2Obj;
|
||||
if (i == 0) {
|
||||
r2Obj = Undefined.INSTANCE;
|
||||
} else if (i == 1) {
|
||||
r2Obj = Null.INSTANCE;
|
||||
} else if (i == 2) {
|
||||
r2Obj = false;
|
||||
} else if (i == 3) {
|
||||
r2Obj = true;
|
||||
} else if (i == 4) {
|
||||
r2Obj = "";
|
||||
} else if (i == 5) {
|
||||
r2Obj = "test";
|
||||
} else if (i == 6) {
|
||||
r2Obj = "0";
|
||||
} else if (i == 7) {
|
||||
r2Obj = "0.0";
|
||||
} else if (i == 8) {
|
||||
r2Obj = "1.0";
|
||||
} else if (i == 9) {
|
||||
r2Obj = "-1.0";
|
||||
} else if (i == 10) {
|
||||
r2Obj = 0;
|
||||
} else if (i == 11) {
|
||||
r2Obj = -100;
|
||||
} else if (i == 12) {
|
||||
r2Obj = 100;
|
||||
} else {
|
||||
r2Obj = r2;
|
||||
}
|
||||
|
||||
newActions.add(new ActionPush(r2Obj));
|
||||
|
||||
System.out.println(i + " " + j + " " + opAction.toString() + " r1:" + r1 + " r2:" + r2Obj + " r3:" + "mystring");
|
||||
newActions.add(opAction);
|
||||
newActions.add(new ActionPushDuplicate());
|
||||
newActions.add(new ActionTypeOf());
|
||||
newActions.add(new ActionStackSwap());
|
||||
newActions.add(new ActionStringAdd());
|
||||
actions.addActions(2, newActions);
|
||||
|
||||
List<GraphTargetItem> output = new ArrayList<>();
|
||||
ActionLocalData localData = new ActionLocalData();
|
||||
TranslateStack stack = new TranslateStack("");
|
||||
for (Action a : newActions) {
|
||||
a.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
|
||||
}
|
||||
|
||||
Object ffdecResult = stack.pop().getResult();
|
||||
System.out.println("FFDec result: " + ffdecResult);
|
||||
|
||||
if (!ffdecResult.equals(flashResult)) {
|
||||
LocalDataArea lda = new LocalDataArea();
|
||||
for (Action a : newActions) {
|
||||
for (Action a : task.actions) {
|
||||
if (!a.execute(lda)) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
Object ffdecExecuteResult = lda.stack.pop();
|
||||
System.out.println("FFDec execte result: " + ffdecExecuteResult);
|
||||
|
||||
asm.setActions(actions);
|
||||
asm.setModified();
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f2))) {
|
||||
swf.saveTo(fos);
|
||||
}
|
||||
|
||||
flash.setMovie(f2.getAbsolutePath());
|
||||
|
||||
synchronized (lockObj) {
|
||||
lockObj.wait();
|
||||
}
|
||||
|
||||
String str = flash.GetVariable("myText.text");
|
||||
String flashResult = resultRef.getVal();
|
||||
boolean checkOnlyStart = false;
|
||||
/*if (flashResult.length() > 10) {
|
||||
boolean onlyNumber = true;
|
||||
for (int k = 0; k < 10; k++) {
|
||||
char ch = flashResult.charAt(flashResult.length() - k - 1);
|
||||
if (ch < '0' || ch > '9') {
|
||||
onlyNumber = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (onlyNumber) {
|
||||
flashResult = flashResult.substring(0, flashResult.length() - 1);
|
||||
checkOnlyStart = true;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (checkOnlyStart) {
|
||||
Assert.assertTrue(((String) ffdecResult).startsWith(flashResult));
|
||||
Assert.assertTrue(((String) ffdecExecuteResult).startsWith(flashResult));
|
||||
} else {
|
||||
Assert.assertEquals(ffdecResult, flashResult);
|
||||
Assert.assertEquals(ffdecExecuteResult, flashResult);
|
||||
}
|
||||
|
||||
f2.delete();
|
||||
Object res = lda.stack.pop();
|
||||
}
|
||||
|
||||
if (checkOnlyStart) {
|
||||
assertTrue(((String) ffdecResult).startsWith(flashResult));
|
||||
} else {
|
||||
assertEquals(ffdecResult, flashResult);
|
||||
}
|
||||
expeced.append(task.description).append(task.flashResult).append(Helper.newLine);
|
||||
current.append(task.description).append(task.ffdecResult).append(Helper.newLine);
|
||||
}
|
||||
|
||||
Helper.writeFile("c:\\1\\expected.txt", Utf8Helper.getBytes(expeced.toString()));
|
||||
Helper.writeFile("c:\\1\\current.txt", Utf8Helper.getBytes(current.toString()));
|
||||
}
|
||||
|
||||
private Object[] getAs2Pushes() {
|
||||
int r1 = random.nextInt(500) - 255;
|
||||
int r2 = random.nextInt(100);
|
||||
Object[] pushes = new Object[]{
|
||||
Undefined.INSTANCE, Null.INSTANCE,
|
||||
false, true,
|
||||
Double.NaN,
|
||||
"", "-2147483649", "-2147483648", "-2147483647", "-1", "0", "1", "2147483647", "2147483648", "4294967295", "4294967296", "1test", "test", "0.0", "1.0", "-1.0",
|
||||
-1.0, -0.5, 0, 0.5, 1.0,
|
||||
-2147483648, -2147483647, -1073741824, -1073741823, -536870912, -536870911, -268435456, -134217728, -134217727, -67108864, -67108863, -33554432,
|
||||
-33554431, -16777216, -16777215, -8388608, -8388607, -4194304, -4194303, -2097152, -2097151, -1048576, -1048575, -524288, -524287, -262144, -262143, -131072, -131071, -65536, -65535, -32768, -32767, -1, 0, 1, 32767, 32768, 268435455,
|
||||
-100, 100,
|
||||
//r1, r2
|
||||
-225, 66
|
||||
};
|
||||
return pushes;
|
||||
}
|
||||
|
||||
private Action getOpAction(int idx) {
|
||||
Action result;
|
||||
if (idx < 13) {
|
||||
result = getUnaryOpAction(idx);
|
||||
Assert.assertEquals(1, result.getStackPopCount(null, null));
|
||||
Assert.assertEquals(1, result.getStackPushCount(null, null));
|
||||
assertEquals(1, result.getStackPopCount(null, null));
|
||||
assertEquals(1, result.getStackPushCount(null, null));
|
||||
} else if (idx < 13 + 23) {
|
||||
result = getBinaryOpAction(idx - 13);
|
||||
Assert.assertEquals(2, result.getStackPopCount(null, null));
|
||||
Assert.assertEquals(1, result.getStackPushCount(null, null));
|
||||
assertEquals(2, result.getStackPopCount(null, null));
|
||||
assertEquals(1, result.getStackPushCount(null, null));
|
||||
} else {
|
||||
result = getTernaryOpAction(idx - 13 - 23);
|
||||
Assert.assertEquals(3, result.getStackPopCount(null, null));
|
||||
Assert.assertEquals(1, result.getStackPushCount(null, null));
|
||||
assertEquals(3, result.getStackPopCount(null, null));
|
||||
assertEquals(1, result.getStackPushCount(null, null));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user