diff --git a/CHANGELOG.md b/CHANGELOG.md index e23a58b71..2d8c0efa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. - [#2636] ActionScript 3 - Incorrect switch detection - AS3 property resolving for KIND_NAMESPACE (like builtin for Strings, etc.) - [#2636] ActionScript - switches vs loop breaks +- [#2636] ActionScript 3 - type coercion / convert, local registers type propagation ## [25.1.0] - 2026-02-17 ### Added diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 24a11652c..5cb1274cb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -2201,6 +2201,11 @@ public class AVM2Code implements Cloneable { vtype = assignment.value.returnType(); } else if (assignment.value instanceof LocalRegAVM2Item) { vtype = assignment.value.returnType(); + } else { + vtype = assignment.value.returnType(); + if (vtype == TypeItem.UNKNOWN) { + vtype = TypeItem.UNBOUNDED; + } } } @@ -2435,12 +2440,21 @@ public class AVM2Code implements Cloneable { handleDeclareReg(minreg, subItem, declaredRegisters, declaredSlots, reg); } } + /* if (subItem instanceof LocalRegAVM2Item) { LocalRegAVM2Item getLocal = (LocalRegAVM2Item) subItem; if (declaredRegisters[getLocal.regIndex] != null) { getLocal.type = declaredRegisters[getLocal.regIndex].type; } } + + if (subItem instanceof SetLocalAVM2Item) { + SetLocalAVM2Item setLocal = (SetLocalAVM2Item) subItem; + if (declaredRegisters[setLocal.regIndex] != null) { + setLocal.type = declaredRegisters[setLocal.regIndex].type; + } + } + */ if (subItem instanceof SetPropertyAVM2Item) { SetPropertyAVM2Item sp = (SetPropertyAVM2Item) subItem; if (sp.object instanceof FindPropertyAVM2Item) { @@ -2952,9 +2966,44 @@ public class AVM2Code implements Cloneable { paramNamesList.add(AVM2Item.localRegName(abc.getSwf(), localRegNames, ir, usedDeobfuscations)); } injectDeclarations(usedDeobfuscations, 0, paramNamesList, list, 1, d, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), abc, body); - + uniteLocalsDeclarationTypes(d, list); return list; } + + private void uniteLocalsDeclarationTypes(DeclarationAVM2Item[] declaredRegs, List items) { + for (int i = 0; i < items.size(); i++) { + GraphTargetItem currentItem = items.get(i); + List itemsOnLine = new ArrayList<>(); + itemsOnLine.add(currentItem); + currentItem.visitRecursivelyNoBlock(new AbstractGraphTargetRecursiveVisitor() { + @Override + public void visit(GraphTargetItem item, Stack parentStack) { + itemsOnLine.add(item); + } + }); + + for (GraphTargetItem item : itemsOnLine) { + if (item instanceof SetLocalAVM2Item) { + SetLocalAVM2Item setLocal = (SetLocalAVM2Item) item; + if (declaredRegs[setLocal.regIndex] != null) { + setLocal.type = declaredRegs[setLocal.regIndex].type; + } + } + if (item instanceof LocalRegAVM2Item) { + LocalRegAVM2Item getLocal = (LocalRegAVM2Item) item; + if (declaredRegs[getLocal.regIndex] != null) { + getLocal.type = declaredRegs[getLocal.regIndex].type; + } + } + } + if (currentItem instanceof Block) { + Block block = (Block) currentItem; + for (List sub : block.getSubs()) { + uniteLocalsDeclarationTypes(declaredRegs, sub); + } + } + } + } /** * Updates instruction byte count at given address. diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java index 81106fa9b..d2d56489d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java @@ -43,20 +43,33 @@ import java.util.List; public interface SetTypeIns { /** - * Handles number to int conversion. + * Handles setting value with coerce * * @param value Value to convert * @param type Type to convert to * @return Value */ - public static GraphTargetItem handleNumberToInt(GraphTargetItem value, GraphTargetItem type) { - if ((value instanceof ConvertAVM2Item) || (value instanceof CoerceAVM2Item)) { - if (type != null && (type.equals(TypeItem.INT) || type.equals(TypeItem.UINT))) { - if (value.value.returnType().equals(TypeItem.NUMBER)) { - return value.value; - } + public static GraphTargetItem handleSetCoerce(GraphTargetItem value, GraphTargetItem type) { + if (type == null) { + return value; + } + if (!(value instanceof ConvertAVM2Item) && !(value instanceof CoerceAVM2Item)) { + return value; + } + + GraphTargetItem convertType = value.returnType(); + GraphTargetItem insideConvertType = value.value.returnType(); + + if (type.equals(convertType)) { + if (insideConvertType.equals(TypeItem.UNBOUNDED) && !type.equals(TypeItem.UNBOUNDED)) { + return value.value; } } + + if ((type.equals(TypeItem.INT) || type.equals(TypeItem.UINT)) && insideConvertType.equals(TypeItem.NUMBER)) { + return value.value; + } + return value; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java index f425c529d..885c69c28 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java @@ -22,6 +22,8 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; +import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; @@ -35,6 +37,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.CommaExpressionItem; import com.jpexs.decompiler.graph.model.CompoundableBinaryOp; import com.jpexs.decompiler.graph.model.DuplicateItem; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java index 8f176bd23..6a27946fb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java @@ -79,30 +79,30 @@ public class CoerceAVM2Item extends AVM2Item { break; case "Boolean": displayCoerce = !valueReturnType.equals(TypeItem.BOOLEAN) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "Number": displayCoerce = !valueReturnType.equals(TypeItem.INT) && !valueReturnType.equals(TypeItem.NUMBER) && !valueReturnType.equals(TypeItem.UINT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "float": displayCoerce = !valueReturnType.equals(TypeItem.INT) && !valueReturnType.equals(new TypeItem("float")) && !valueReturnType.equals(TypeItem.UINT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "int": displayCoerce = !valueReturnType.equals(TypeItem.INT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "uint": if (valueReturnType.equals(TypeItem.INT) && (value instanceof IntegerValueAVM2Item)) { displayCoerce = (((IntegerValueAVM2Item) value).value < 0); } else { displayCoerce = !valueReturnType.equals(TypeItem.UINT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;// && !valueReturnType.equals(TypeItem.UNBOUNDED); } break; case "String": diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java index 94109e291..cb02616bf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java @@ -67,30 +67,30 @@ public class ConvertAVM2Item extends AVM2Item { switch (type.toString()) { case "Boolean": displayConvert = !valueReturnType.equals(TypeItem.BOOLEAN) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "Number": displayConvert = !valueReturnType.equals(TypeItem.INT) && !valueReturnType.equals(TypeItem.NUMBER) && !valueReturnType.equals(TypeItem.UINT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "float": displayConvert = !valueReturnType.equals(TypeItem.INT) && !valueReturnType.equals(new TypeItem("float")) && !valueReturnType.equals(TypeItem.UINT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "int": displayConvert = !valueReturnType.equals(TypeItem.INT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; case "uint": if (valueReturnType.equals(TypeItem.INT) && (value instanceof IntegerValueAVM2Item)) { displayConvert = (((IntegerValueAVM2Item) value).value < 0); } else { displayConvert = !valueReturnType.equals(TypeItem.UINT) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;// && !valueReturnType.equals(TypeItem.UNBOUNDED); } break; case "String": @@ -98,7 +98,7 @@ public class ConvertAVM2Item extends AVM2Item { //&& !valueReturnType.equals(new TypeItem("XML")) //&& !valueReturnType.equals(new TypeItem("XMLList")) && !valueReturnType.equals(new TypeItem("null")) - && !valueReturnType.equals(TypeItem.UNBOUNDED); + ;//&& !valueReturnType.equals(TypeItem.UNBOUNDED); break; } if (displayConvert) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java index 82d9d636d..dd25f24b7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java @@ -120,7 +120,7 @@ public class SetLocalAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assig /*if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) { return value.value.toString(writer, localData); }*/ - return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData); + return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetPropertyAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetPropertyAVM2Item.java index 524f2b21d..50cc8ca7b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetPropertyAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetPropertyAVM2Item.java @@ -140,7 +140,7 @@ public class SetPropertyAVM2Item extends AVM2Item implements SetTypeAVM2Item, As /*if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) { return value.value.toString(writer, localData); }*/ - return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData); + return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData); } @Override @@ -167,7 +167,7 @@ public class SetPropertyAVM2Item extends AVM2Item implements SetTypeAVM2Item, As @Override public GraphTargetItem returnType() { - return value.returnType(); + return type; //return TypeItem.UNBOUNDED; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java index cc7dc63c0..911e265ef 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java @@ -139,7 +139,7 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign /*if (declaration != null && !declaration.type.equals(TypeItem.UNBOUNDED) && (value instanceof ConvertAVM2Item)) { return value.value.toString(writer, localData); }*/ - return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData); + return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData); } /** @@ -183,7 +183,7 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign @Override public GraphTargetItem returnType() { - return TypeItem.UNBOUNDED; + return type; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSuperAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSuperAVM2Item.java index 26a7796d6..2acd1bbb9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSuperAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSuperAVM2Item.java @@ -135,7 +135,7 @@ public class SetSuperAVM2Item extends AVM2Item implements SetTypeAVM2Item { return compoundValue.toString(writer, localData); } writer.append(" = "); - return SetTypeIns.handleNumberToInt(value, type).toString(writer, localData); + return SetTypeIns.handleSetCoerce(value, type).toString(writer, localData); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java index 2f034a1e2..bc9511972 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java @@ -130,7 +130,7 @@ public class DeclarationAVM2Item extends AVM2Item { type.appendTry(writer, localData); if (showValue) { writer.append(" = "); - SetTypeIns.handleNumberToInt(val, type).toString(writer, localData); + SetTypeIns.handleSetCoerce(val, type).toString(writer, localData); } return writer; } @@ -149,7 +149,7 @@ public class DeclarationAVM2Item extends AVM2Item { type.appendTry(writer, localData); if (showValue) { writer.append(" = "); - SetTypeIns.handleNumberToInt(val, type).toString(writer, localData); + SetTypeIns.handleSetCoerce(val, type).toString(writer, localData); } return writer; } @@ -169,7 +169,7 @@ public class DeclarationAVM2Item extends AVM2Item { type.appendTry(writer, localData); if (showValue) { writer.append(" = "); - SetTypeIns.handleNumberToInt(val, type).toString(writer, localData); + SetTypeIns.handleSetCoerce(val, type).toString(writer, localData); } return writer; } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java index e1b3aa1cd..a3bf0d1ba 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java @@ -105,7 +105,7 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT public void testDecrementPrecedence() { decompileMethod("assembled", "testDecrementPrecedence", "var _loc2_:int = 10;\r\n" + "var _loc1_:int = 5;\r\n" - + "var _loc3_:* = _loc2_ & (1 << _loc1_) - 1;\r\n", + + "var _loc3_:int = _loc2_ & (1 << _loc1_) - 1;\r\n", false); } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java index c06bb2b33..b59e8dcc7 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java @@ -47,7 +47,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testAlwaysBreak() { - decompileMethod("classic_air", "testAlwaysBreak", "var v:* = undefined;\r\n" + decompileMethod("classic_air", "testAlwaysBreak", "var v:int = 0;\r\n" + "v = 5;\r\n" + "trace(\"a\");\r\n" + "while(true)\r\n" @@ -75,7 +75,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile + "var y:TestInterface = ti && (ti = new TestClass());\r\n" + "var z:TestClass = tc || (tc = new TestClass());\r\n" + "this.ti = ti && (ti = new TestClass());\r\n" - + "var a:* = ti && (ti = new TestClass());\r\n" + + "var a:Boolean = ti && (ti = new TestClass());\r\n" + "var b:int = 1 + (i || j);\r\n" + "test(ti && (ti = new TestClass()));\r\n" + "return ti && (ti = new TestClass());\r\n", @@ -91,20 +91,20 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testBitwiseOperands() { decompileMethod("classic_air", "testBitwiseOperands", "var a:int = 100;\r\n" - + "var b:* = a & 0x08FF;\r\n" - + "var c:* = 0x08FF & a;\r\n" - + "var d:* = a | 0x0480;\r\n" - + "var e:* = 0x0480 | a;\r\n" - + "var f:* = a ^ 0x0641;\r\n" - + "var g:* = 0x0641 ^ a;\r\n" + + "var b:int = a & 0x08FF;\r\n" + + "var c:int = 0x08FF & a;\r\n" + + "var d:int = a | 0x0480;\r\n" + + "var e:int = 0x0480 | a;\r\n" + + "var f:int = a ^ 0x0641;\r\n" + + "var g:int = 0x0641 ^ a;\r\n" + "var h:int = -385;\r\n", false); } @Test public void testCallCall() { - decompileMethod("classic_air", "testCallCall", "var o:* = new getDefinitionByName(\"Object\");\r\n" - + "var o2:* = new (getDefinitionByName(\"Object\"))();\r\n", + decompileMethod("classic_air", "testCallCall", "var o:Function = new getDefinitionByName(\"Object\");\r\n" + + "var o2:Object = new (getDefinitionByName(\"Object\"))();\r\n", false); } @@ -244,7 +244,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testCompoundAssignments() { - decompileMethod("classic_air", "testCompoundAssignments", "var b:* = [10,20,30];\r\n" + decompileMethod("classic_air", "testCompoundAssignments", "var b:Array = [10,20,30];\r\n" + "var a:int = 0;\r\n" + "trace(\"a += 5\");\r\n" + "a += 5;\r\n" @@ -343,8 +343,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile + "var i:int = 0;\r\n" + "var a:* = undefined;\r\n" + "var dict:Dictionary = new Dictionary();\r\n" - + "s = \"a\";\r\n" - + "i = int(s);\r\n" + + "i = int(s = \"a\");\r\n" + "var j:int = n;\r\n" + "s = String(j);\r\n" + "s = ns;\r\n" @@ -417,7 +416,11 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile + "super.prot = 1.5;\r\n" + "super.prot = int(s);\r\n" + "i = super.prot;\r\n" - + "s = String(super.prot);\r\n", + + "s = String(super.prot);\r\n" + + "var a2:* = \"5\";\r\n" + + "var s2:String = \"s\";\r\n" + + "var i2:int = a2;\r\n" + + "a2 = Number(a2);\r\n", false); } @@ -608,7 +611,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testDotParent() { - decompileMethod("classic_air", "testDotParent", "var d:* = new TestClass1();\r\n" + decompileMethod("classic_air", "testDotParent", "var d:TestClass1 = new TestClass1();\r\n" + "var k:* = null;\r\n" + "k.(d.attrib++,false);\r\n" + "trace(\"between\");\r\n" @@ -816,7 +819,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testForEachReturn2() { - decompileMethod("classic_air", "testForEachReturn2", "var obj:* = null;\r\n" + decompileMethod("classic_air", "testForEachReturn2", "var obj:Object = null;\r\n" + "var x:int = 5;\r\n" + "if(x != null)\r\n" + "{\r\n" @@ -1369,7 +1372,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile public void testImplicitCoerce() { decompileMethod("classic_air", "testImplicitCoerce", "var j:int = 2;\r\n" + "var i:int = 5;\r\n" - + "var r:* = Math.random();\r\n" + + "var r:Number = Math.random();\r\n" + "if(j & Number(r == 1) && 5)\r\n" + "{\r\n" + "trace(\"OK\");\r\n" @@ -1425,7 +1428,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec3() { - decompileMethod("classic_air", "testIncDec3", "var a:* = [1,2,3,4,5];\r\n" + decompileMethod("classic_air", "testIncDec3", "var a:Array = [1,2,3,4,5];\r\n" + "trace(\"++a[2] with result\");\r\n" + "trace(++a[2]);\r\n" + "trace(\"--a[2] with result\");\r\n" @@ -1439,7 +1442,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec4() { - decompileMethod("classic_air", "testIncDec4", "var a:* = [1,2,3,4,5];\r\n" + decompileMethod("classic_air", "testIncDec4", "var a:Array = [1,2,3,4,5];\r\n" + "trace(\"a[2]++ with result\");\r\n" + "trace(a[2]++);\r\n" + "trace(\"a[2]-- with result\");\r\n" @@ -1453,7 +1456,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec5() { - decompileMethod("classic_air", "testIncDec5", "var a:* = new TestClass1();\r\n" + decompileMethod("classic_air", "testIncDec5", "var a:TestClass1 = new TestClass1();\r\n" + "trace(\"++a.attrib with result\");\r\n" + "trace(++a.attrib);\r\n" + "trace(\"--a.attrib with result\");\r\n" @@ -1467,7 +1470,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec6() { - decompileMethod("classic_air", "testIncDec6", "var a:* = new TestClass1();\r\n" + decompileMethod("classic_air", "testIncDec6", "var a:TestClass1 = new TestClass1();\r\n" + "trace(\"a.attrib++ with result\");\r\n" + "trace(a.attrib++);\r\n" + "trace(\"a.attrib-- with result\");\r\n" @@ -1481,7 +1484,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec7() { - decompileMethod("classic_air", "testIncDec7", "var a:* = [1,2,3,4,5];\r\n" + decompileMethod("classic_air", "testIncDec7", "var a:Array = [1,2,3,4,5];\r\n" + "var index:int = 0;\r\n" + "trace(\"a[++index]\");\r\n" + "trace(a[++index]);\r\n" @@ -1492,7 +1495,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec8() { - decompileMethod("classic_air", "testIncDec8", "var a:* = [1,2,3,4,5];\r\n" + decompileMethod("classic_air", "testIncDec8", "var a:Array = [1,2,3,4,5];\r\n" + "var index:int = 0;\r\n" + "trace(\"a[index++]\");\r\n" + "trace(a[index++]);\r\n" @@ -1563,7 +1566,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec13() { - decompileMethod("classic_air", "testIncDec13", "var a:* = [1,2,3,4,5];\r\n" + decompileMethod("classic_air", "testIncDec13", "var a:Array = [1,2,3,4,5];\r\n" + "trace(\"++a[this.f()] with result\");\r\n" + "trace(++a[this.f()]);\r\n" + "trace(\"--a[this.f()] with result\");\r\n" @@ -1577,7 +1580,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testIncDec14() { - decompileMethod("classic_air", "testIncDec14", "var a:* = [1,2,3,4,5];\r\n" + decompileMethod("classic_air", "testIncDec14", "var a:Array = [1,2,3,4,5];\r\n" + "trace(\"a[this.f()]++ with result\");\r\n" + "trace(a[this.f()]++);\r\n" + "trace(\"a[this.f()]-- with result\");\r\n" @@ -1826,8 +1829,8 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testNames() { - decompileMethod("classic_air", "testNames", "var ns:* = this.getNamespace();\r\n" - + "var name:* = this.getName();\r\n" + decompileMethod("classic_air", "testNames", "var ns:Namespace = this.getNamespace();\r\n" + + "var name:String = this.getName();\r\n" + "var a:* = ns::unnamespacedFunc();\r\n" + "var b:* = ns::[name];\r\n" + "trace(b.c);\r\n" @@ -1869,8 +1872,8 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testOperations() { decompileMethod("classic_air", "testOperations", "var cr:MyClass = null;\r\n" - + "var br:* = false;\r\n" - + "var r:* = NaN;\r\n" + + "var br:Boolean = false;\r\n" + + "var r:Number = NaN;\r\n" + "var v:* = undefined;\r\n" + "var xlr:XMLList = null;\r\n" + "var sr:String = null;\r\n" @@ -2037,8 +2040,8 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile decompileMethod("classic_air", "testPrecedenceX", "var a:int = 5;\r\n" + "var b:int = 2;\r\n" + "var c:int = 3;\r\n" - + "var d:* = a << (b >>> c);\r\n" - + "var e:* = a << b >>> c;\r\n", + + "var d:int = a << (b >>> c);\r\n" + + "var e:int = a << b >>> c;\r\n", false); } @@ -2056,10 +2059,10 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testRegExp() { decompileMethod("classic_air", "testRegExp", "var r:Number = NaN;\r\n" - + "var a1:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n" - + "var a2:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n" - + "var b1:* = /[0-9AB]+/;\r\n" - + "var b2:* = /[0-9AB]+/;\r\n" + + "var a1:RegExp = /[a-z\\r\\n0-9\\\\]+/i;\r\n" + + "var a2:RegExp = /[a-z\\r\\n0-9\\\\]+/i;\r\n" + + "var b1:RegExp = /[0-9AB]+/;\r\n" + + "var b2:RegExp = /[0-9AB]+/;\r\n" + "var n1:Number = 5;\r\n" + "var n2:Number = 2;\r\n" + "var n3:Number = 1;\r\n" @@ -2306,7 +2309,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile + "var b:int = 4;\r\n" + "var c:int = 4;\r\n" + "var d:int = 78;\r\n" - + "var e:* = a == b ? (c == d ? 1 : 7) : 3;\r\n" + + "var e:Number = a == b ? (c == d ? 1 : 7) : 3;\r\n" + "trace(\"e=\" + e);\r\n", false); } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java index 867ebf862..e8f466966 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java @@ -47,7 +47,7 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes @Test public void testAlwaysBreak() { - decompileMethod("classic", "testAlwaysBreak", "var v:* = undefined;\r\n" + decompileMethod("classic", "testAlwaysBreak", "var v:int = 0;\r\n" + "v = 5;\r\n" + "trace(\"a\");\r\n" + "while(true)\r\n" @@ -416,7 +416,11 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes + "super.prot = 1.5;\r\n" + "super.prot = int(s);\r\n" + "i = super.prot;\r\n" - + "s = String(super.prot);\r\n", + + "s = String(super.prot);\r\n" + + "var a2:* = \"5\";\r\n" + + "var s2:String = \"s\";\r\n" + + "var i2:int = a2;\r\n" + + "a2 = Number(a2);\r\n", false); } @@ -579,16 +583,16 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes @Test public void testDoWhileTwice() { - decompileMethod("classic", "testDoWhileTwice", "var a:* = 1;\r\n" - + "var b:* = 2;\r\n" + decompileMethod("classic", "testDoWhileTwice", "var a:int = 1;\r\n" + + "var b:int = 2;\r\n" + "do\r\n" + "{\r\n" + "do\r\n" + "{\r\n" - + "if(a)\r\n" + + "if(Boolean(a))\r\n" + "{\r\n" + "trace(\"x\");\r\n" - + "if(b)\r\n" + + "if(Boolean(b))\r\n" + "{\r\n" + "break;\r\n" + "}\r\n" @@ -598,7 +602,7 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes + "}\r\n" + "while(true);\r\n" + "trace(\"g\");\r\n" - + "if(b)\r\n" + + "if(Boolean(b))\r\n" + "{\r\n" + "break;\r\n" + "}\r\n" @@ -1825,7 +1829,7 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes decompileMethod("classic", "testNames", "var ns:* = this.getNamespace();\r\n" + "var name:* = this.getName();\r\n" + "var a:* = ns::unnamespacedFunc();\r\n" - + "var b:* = ns::[name];\r\n" + + "var b:* = ns::[String(name)];\r\n" + "trace(b.c);\r\n" + "var c:* = myInternal::neco;\r\n" + "var d:* = this.myInternal2::neco;\r\n", diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java index 9dd8e15c6..3b46fb1af 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java @@ -521,9 +521,9 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript @Test public void testTryCatchWith() { - decompileMethod("swftools", "testTryCatchWith", "var _loc1_:* = new MyTest();\r\n" + decompileMethod("swftools", "testTryCatchWith", "var _loc1_:MyTest = new MyTest();\r\n" + "trace(\"before with\");\r\n" - + "var _loc2_:* = _loc1_;\r\n" + + "var _loc2_:MyTest = _loc1_;\r\n" + "with(_loc2_)\r\n" + "{\r\n" + "trace(\"before try\");\r\n" diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf index 5aea380e6..e1deee83f 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf index 89ee54f89..81ebeacfd 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestAlwaysBreak.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestAlwaysBreak.as index c637e9cd8..685eb17e3 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestAlwaysBreak.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestAlwaysBreak.as @@ -7,7 +7,7 @@ package tests { while(true) { - var v = 5; + var v:int = 5; trace("a"); if(v > 4) { diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestConvert.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestConvert.as index fa265d4b0..e03e8430c 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestConvert.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestConvert.as @@ -109,10 +109,15 @@ package tests i = super.prot; s = String(super.prot); + + var a2:* = "5"; + var s2:String = "s"; + var i2:int = a2; + a2 = Number(a2); } } } class LocalClass{ public var attr:int = 5; -} \ No newline at end of file +} diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestDoWhileTwice.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestDoWhileTwice.as index c0b583e0c..4335c188b 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestDoWhileTwice.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestDoWhileTwice.as @@ -5,8 +5,8 @@ package tests { public function run():* { - var a = 1; - var b = 2; + var a:int = 1; + var b:int = 2; do { do { if (a) { diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestHello.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestHello.as index bab1fbc87..3f81d98b8 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestHello.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestHello.as @@ -5,7 +5,7 @@ package tests { public function run():* { - trace("hello"); + trace("hello"); } } }