diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c3a48ef..065aa77e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### Fixed - [#2636] ActionScript - Incorrect always-break detection causing insertion of while(true) - [#2636] ActionScript 3 - Incorrect switch detection +- AS3 property resolving for KIND_NAMESPACE (like builtin for Strings, etc.) ## [25.1.0] - 2026-02-17 ### Added diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java index 315f1d28a..3e5620ccb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -108,21 +108,16 @@ public final class AbcIndexing { * Property key */ public static class PropertyDef { - - private static final String BUILT_IN_NS = "http://adobe.com/AS3/2006/builtin"; - - private static Map builtInNsPerAbc = new WeakHashMap<>(); - private final String propName; + + private final GraphTargetItem parent; private String propNsString = null; - private final GraphTargetItem parent; - private int propNsIndex = 0; private ABC abc = null; - + /** * To string * @return String @@ -131,17 +126,7 @@ public final class AbcIndexing { public String toString() { return parent.toString() + ":" + propName + (propNsIndex > 0 ? "[ns:" + propNsIndex + "]" : "") + (propNsString != null ? "[ns: " + propNsString + "]" : ""); } - - private void setPrivate(ABC abc, int propNsIndex) { - this.propNsIndex = propNsIndex; - this.abc = abc; - } - - private void setProtected(ABC abc, int propNsIndex) { - this.abc = null; - this.propNsString = abc.constants.getNamespace(propNsIndex).getRawName(abc.constants); - } - + /** * Gets property name * @return Property name @@ -163,39 +148,30 @@ public final class AbcIndexing { * * @param propName Name of the property * @param parent Parent type (usually TypeItem) - * @param abc ABC for private/protected namespace resolving + * @param abc ABC for private/protected/namespace namespace resolving * @param propNsIndex Index of property(trait) namespace for - * private/protected namespace resolving + * private/protected/namespace namespace resolving */ - public PropertyDef(String propName, GraphTargetItem parent, ABC abc, int propNsIndex) { - - int builtInIndex = -1; - if (abc != null) { - Integer builtInNs = builtInNsPerAbc.get(abc); - - if (builtInNs == null) { - //we need to avoid modifying the ABC - /* builtInIndex = abc.constants.getNamespaceId(Namespace.KIND_NAMESPACE, BUILT_IN_NS, 0, true); - builtInNsPerAbc.put(abc, builtInIndex);*/ - builtInIndex = Integer.MIN_VALUE; //?? - } else { - builtInIndex = builtInNs; - } - } + public PropertyDef(String propName, GraphTargetItem parent, ABC abc, int propNsIndex) { this.propName = propName; this.parent = parent; if (abc == null || propNsIndex <= 0) { return; } - int k = abc.constants.getNamespace(propNsIndex).kind; - if (k != Namespace.KIND_PACKAGE && propNsIndex != builtInIndex) { - if (k == Namespace.KIND_PROTECTED || k == Namespace.KIND_STATIC_PROTECTED) { - setProtected(abc, propNsIndex); - } else { - setPrivate(abc, propNsIndex); - } - } + Namespace ns = abc.constants.getNamespace(propNsIndex); + switch (ns.kind) { + case Namespace.KIND_PACKAGE: + case Namespace.KIND_NAMESPACE: + case Namespace.KIND_PROTECTED: + case Namespace.KIND_STATIC_PROTECTED: + this.abc = null; + this.propNsString = abc.constants.getNamespace(propNsIndex).getRawName(abc.constants); + break; + default: + this.abc = abc; + this.propNsIndex = propNsIndex; + } } /** @@ -910,6 +886,15 @@ public final class AbcIndexing { } } if (parent != null) { + if (prop.propNsIndex != 0) { + /*Namespace ns = getSelectedAbc().constants.getNamespace(prop.propNsIndex); + if (ns.kind == Namespace.KIND_NAMESPACE) { + ABC parentAbc = parent.getSelectedAbc(); + AVM2ConstantPool parentConstants = parentAbc.constants; + int parentNsId = parentConstants.getNamespaceId(Namespace.KIND_NAMESPACE, parentConstants.getStringId(ns.getName(getSelectedAbc().constants), false), 0, false); + prop = new PropertyDef(prop.propName, prop.parent, parentAbc, parentNsId); + }*/ + } TraitIndex pti = parent.findProperty(prop, findStatic, findInstance, findProtected, foundStatic); if (pti != null) { return pti; 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 ff93da4e7..e1b3aa1cd 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 @@ -17,7 +17,6 @@ package com.jpexs.decompiler.flash.as3decompile; import com.jpexs.decompiler.flash.ActionScript3DecompileTestBase; -import com.jpexs.decompiler.flash.configuration.Configuration; import java.io.IOException; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; 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 60720bf24..c06bb2b33 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 @@ -2070,6 +2070,12 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile false); } + @Test + public void testResolvingBuildIn() { + decompileMethod("classic_air", "testResolvingBuildIn", "var i:int = \"Hello world\".indexOf(\"world\");\r\n", + false); + } + @Test public void testRest() { decompileMethod("classic_air", "testRest", "trace(\"firstRest:\" + restval[0]);\r\n" 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 5e93b5918..867ebf862 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 @@ -2060,6 +2060,12 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes false); } + @Test + public void testResolvingBuildIn() { + decompileMethod("classic", "testResolvingBuildIn", "var i:int = \"Hello world\".indexOf(\"world\");\r\n", + false); + } + @Test public void testRest() { decompileMethod("classic", "testRest", "trace(\"firstRest:\" + restval[0]);\r\n" diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java index 1b9a49f66..adebed50f 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java @@ -195,6 +195,8 @@ public class AS3Generator { public static void main(String[] args) throws Exception { Configuration.autoDeobfuscate.set(false); Configuration.showMethodBodyId.set(false); + Configuration.autoDeobfuscateIdentifiers.set(false); + Configuration.as3QNameObfuscatedPropsInSquareBrackets.set(true); Configuration.simplifyExpressions.set(false); Configuration.displayDupInstructions.set(true); 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 4bb55f0fb..5aea380e6 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 88a889f3a..89ee54f89 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/Main.as b/libsrc/ffdec_lib/testdata/as3_new/src/Main.as index e1a355ba4..bd6cfa324 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/Main.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/Main.as @@ -128,6 +128,7 @@ package TestPrecedenceX; TestProperty; TestRegExp; + TestResolvingBuildIn; TestRest; TestSlots; TestSlots2; diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestResolvingBuildIn.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestResolvingBuildIn.as new file mode 100644 index 000000000..948097455 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestResolvingBuildIn.as @@ -0,0 +1,11 @@ +package tests +{ + + public class TestResolvingBuildIn + { + public function run():void + { + var i:int = "Hello world".indexOf("world"); + } + } +}