Fixed #1938 "Open loaded during play" Loader injection for Multiname types

This commit is contained in:
Jindra Petřík
2023-01-22 22:15:04 +01:00
parent 2511a80f23
commit 6602ecffa0
2 changed files with 70 additions and 22 deletions
+2 -1
View File
@@ -40,7 +40,8 @@ All notable changes to this project will be documented in this file.
- [#1938] AS3 - shortening + 1 to increment - [#1938] AS3 - shortening + 1 to increment
- [#1938] AS3 - implicit coercion of operations - [#1938] AS3 - implicit coercion of operations
- [#1938] AS3 - initproperty compound operators, increment/decrement - [#1938] AS3 - initproperty compound operators, increment/decrement
- [#1938] "Open loaded during play" Loader injection for Multiname types
## [18.3.2] - 2023-01-10 ## [18.3.2] - 2023-01-10
### Removed ### Removed
- [#1935], [#1913] Retaining shape exact position(bounds) in SVG export/import - [#1935], [#1913] Retaining shape exact position(bounds) in SVG export/import
@@ -29,6 +29,7 @@ import com.jpexs.decompiler.flash.tags.FileAttributesTag;
import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.helpers.Helper; import com.jpexs.helpers.Helper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.logging.Level; import java.util.logging.Level;
@@ -90,33 +91,79 @@ public class DebuggerTools {
if (hasDebugger(swf)) { if (hasDebugger(swf)) {
ScriptPack dsp = getDebuggerScriptPack(swf); ScriptPack dsp = getDebuggerScriptPack(swf);
String debuggerPkg = dsp.getClassPath().packageStr.toRawString(); String debuggerPkg = dsp.getClassPath().packageStr.toRawString();
List<String> displayTypes = Arrays.asList("Loader");
List<String> utilsTypes = Arrays.asList(
"getDefinitionByName",
"getQualifiedClassName",
"getQualifiedSuperclassName",
"describeType"
);
for (ABCContainerTag ct : swf.getAbcList()) { for (ABCContainerTag ct : swf.getAbcList()) {
ABC a = ct.getABC(); ABC a = ct.getABC();
if (dsp.abc == a) { //do not replace Loader in debugger itself if (dsp.abc == a) { //do not replace Loader in debugger itself
continue; continue;
} }
int debuggerNs = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true);
for (int i = 1; i < a.constants.getMultinameCount(); i++) { for (int i = 1; i < a.constants.getMultinameCount(); i++) {
Multiname m = a.constants.getMultiname(i); Multiname m = a.constants.getMultiname(i);
if ("flash.display.Loader".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { String rawNsName = m.getNameWithNamespace(a.constants, true).toRawString();
m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); if (m.kind == Multiname.MULTINAME) {
m.name_index = a.constants.getStringId("DebugLoader", true); String simpleName = m.getName(a.constants, new ArrayList<>(), true, false);
((Tag) ct).setModified(true); String nsToSearch;
} else if ("flash.utils.getDefinitionByName".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { if (displayTypes.contains(simpleName)) {
m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); nsToSearch = "flash.display";
m.name_index = a.constants.getStringId("debugGetDefinitionByName", true); } else if (utilsTypes.contains(simpleName)) {
((Tag) ct).setModified(true); nsToSearch = "flash.utils";
} else if ("flash.utils.getQualifiedClassName".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { } else {
m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); continue;
m.name_index = a.constants.getStringId("debugGetQualifiedClassName", true); }
((Tag) ct).setModified(true);
} else if ("flash.utils.getQualifiedSuperclassName".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { int nsFoundId = -1;
m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); for (int ns : a.constants.getNamespaceSet(m.namespace_set_index).namespaces) {
m.name_index = a.constants.getStringId("debugGetQualifiedSuperclassName", true); String nsString = a.constants.namespaceToString(ns);
((Tag) ct).setModified(true); if (nsString != null) {
} else if ("flash.utils.describeType".equals(m.getNameWithNamespace(a.constants, true).toRawString())) { if (nsString.equals(nsToSearch)) {
m.namespace_index = a.constants.getNamespaceId(Namespace.KIND_PACKAGE, debuggerPkg, 0, true); nsFoundId = ns;
m.name_index = a.constants.getStringId("debugDescribeType", true); break;
((Tag) ct).setModified(true); }
}
}
if (nsFoundId > -1) {
m.kind = Multiname.QNAME;
m.namespace_index = nsFoundId;
m.namespace_set_index = 0;
rawNsName = m.getNameWithNamespace(a.constants, true).toRawString();
}
}
if (null != rawNsName) {
switch (rawNsName) {
case "flash.display.Loader":
m.namespace_index = debuggerNs;
m.name_index = a.constants.getStringId("DebugLoader", true);
((Tag) ct).setModified(true);
break;
case "flash.utils.getDefinitionByName":
m.namespace_index = debuggerNs;
m.name_index = a.constants.getStringId("debugGetDefinitionByName", true);
((Tag) ct).setModified(true);
break;
case "flash.utils.getQualifiedClassName":
m.namespace_index = debuggerNs;
m.name_index = a.constants.getStringId("debugGetQualifiedClassName", true);
((Tag) ct).setModified(true);
break;
case "flash.utils.getQualifiedSuperclassName":
m.namespace_index = debuggerNs;
m.name_index = a.constants.getStringId("debugGetQualifiedSuperclassName", true);
((Tag) ct).setModified(true);
break;
case "flash.utils.describeType":
m.namespace_index = debuggerNs;
m.name_index = a.constants.getStringId("debugDescribeType", true);
((Tag) ct).setModified(true);
break;
}
} }
} }
} }
@@ -204,7 +251,7 @@ public class DebuggerTools {
} }
} }
//Add to target SWF //Add to target SWF
((Tag) ds).setSwf(swf); ((Tag) ds).setSwf(swf);
swf.addTagBefore((Tag) ds, (Tag) firstAbc); swf.addTagBefore((Tag) ds, (Tag) firstAbc);
swf.getAbcList().add(swf.getAbcList().indexOf(firstAbc), ds); swf.getAbcList().add(swf.getAbcList().indexOf(firstAbc), ds);
((Tag) ds).setModified(true); ((Tag) ds).setModified(true);