From 0ae78aacf3742e1eca68d760f662ffa098308400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Fri, 26 Feb 2021 21:05:17 +0100 Subject: [PATCH] Fixed: AS3 direct editation - compilation of top level classes --- CHANGELOG.md | 1 + .../flash/SourceGeneratorLocalData.java | 2 -- .../src/com/jpexs/decompiler/flash/abc/ABC.java | 3 +++ .../avm2/parser/script/AVM2SourceGenerator.java | 15 +++++++++------ .../avm2/parser/script/ActionScript3Parser.java | 13 ++++++------- .../decompiler/flash/abc/types/traits/Trait.java | 2 +- .../flash/importers/FFDecAs3ScriptReplacer.java | 5 +---- .../flash/ActionScript3DeobfuscatorTest.java | 2 +- .../flash/gui/tagtree/TagTreeContextMenu.java | 2 +- 9 files changed, 23 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c2bfa498..c7cd83348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. - #1450 AS3 direct editation - handling types from same package - AS3 goto definition for types in another ABC tag - AS3 goto definition for obfuscated names +- AS3 direct editation - compilation of top level classes ### Changed - #1616 Close SWF menuitem is last in the context menu diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java index ee5076110..2878e37c8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java @@ -68,8 +68,6 @@ public class SourceGeneratorLocalData implements Serializable { public List scopeStack = new ArrayList<>(); - public boolean documentClass; - public ScriptInfo currentScript; public boolean subMethod = false; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java index b8cfec429..da032de58 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -1372,6 +1372,9 @@ public class ABC { public int findClassByName(String nameWithSuffix) { for (int c = 0; c < instance_info.size(); c++) { + if (instance_info.get(c).deleted) { + continue; + } DottedChain s = constants.getMultiname(instance_info.get(c).name_index).getNameWithNamespace(constants, true); if (nameWithSuffix.equals(s.toRawString())) { return c; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index 405858627..907fa5b1f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -1607,7 +1607,6 @@ public class AVM2SourceGenerator implements SourceGenerator { newlocalData.callStack.addAll(localData.callStack); newlocalData.traitUsages = localData.traitUsages; newlocalData.currentScript = localData.currentScript; - newlocalData.documentClass = localData.documentClass; newlocalData.privateNs = localData.privateNs; newlocalData.protectedNs = localData.protectedNs; newlocalData.isStatic = isStatic; @@ -2463,8 +2462,10 @@ public class AVM2SourceGenerator implements SourceGenerator { for (Trait t : si.traits.traits) { if (t instanceof TraitClass) { TraitClass tc = (TraitClass) t; + DottedChain className = tc.getName(abc).getNameWithNamespace(abc.constants, true); + List parents = new ArrayList<>(); - if (localData.documentClass) { + if (className.size() == 1) { mbCode.add(ins(AVM2Instructions.GetScopeObject, 0)); traitScope++; } else { @@ -2682,19 +2683,21 @@ public class AVM2SourceGenerator implements SourceGenerator { public List generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException { String currentFullClassName = localData.getFullClass(); - if (localData.documentClass && item.toString().equals(currentFullClassName)) { - int slotId = 0; + int globalSlotId = 0; + if (item.fullTypeName.size() == 1 && item.toString().equals(currentFullClassName)) { int c = abcIndex.getSelectedAbc().findClassByName(currentFullClassName); for (Trait t : localData.currentScript.traits.traits) { if (t instanceof TraitClass) { TraitClass tc = (TraitClass) t; if (tc.class_info == c) { - slotId = tc.slot_id; + globalSlotId = tc.slot_id; break; } } } - return GraphTargetItem.toSourceMerge(localData, this, ins(AVM2Instructions.GetGlobalScope), ins(AVM2Instructions.GetSlot, slotId)); + } + if (globalSlotId > 0) { + return GraphTargetItem.toSourceMerge(localData, this, ins(AVM2Instructions.GetGlobalScope), ins(AVM2Instructions.GetSlot, globalSlotId)); } else { return GraphTargetItem.toSourceMerge(localData, this, ins(AVM2Instructions.GetLex, resolveType(localData, item, abcIndex))); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 95fbf4788..31de93005 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -2534,18 +2534,17 @@ public class ActionScript3Parser { return ret; } - public void addScriptFromTree(List> allOpenedNamespaces, List items, boolean documentClass, int classPos) throws AVM2ParseException, CompilationException { + public void addScriptFromTree(List> allOpenedNamespaces, List items, int classPos) throws AVM2ParseException, CompilationException { AVM2SourceGenerator gen = new AVM2SourceGenerator(abcIndex); SourceGeneratorLocalData localData = new SourceGeneratorLocalData( new HashMap<>(), 0, Boolean.FALSE, 0); - localData.documentClass = documentClass; abcIndex.getSelectedAbc().script_info.add(gen.generateScriptInfo(allOpenedNamespaces, localData, items, classPos)); } - public void addScript(String s, boolean documentClass, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, CompilationException { + public void addScript(String s, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, CompilationException { List> allOpenedNamespaces = new ArrayList<>(); List traits = scriptTraitsFromString(allOpenedNamespaces, s, fileName, scriptIndex); - addScriptFromTree(allOpenedNamespaces, traits, documentClass, classPos); + addScriptFromTree(allOpenedNamespaces, traits, classPos); } public ActionScript3Parser(ABC abc, List otherAbcs) throws IOException, InterruptedException { @@ -2571,14 +2570,14 @@ public class ActionScript3Parser { } } - public static void compile(String src, ABC abc, List otherABCs, boolean documentClass, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, InterruptedException, CompilationException { + public static void compile(String src, ABC abc, List otherABCs, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, InterruptedException, CompilationException { //List parABCs = new ArrayList<>(); initPlayer(); ActionScript3Parser parser = new ActionScript3Parser(abc, otherABCs); boolean success = false; ABC originalAbc = ((ABCContainerTag) ((Tag) abc.parentTag).cloneTag()).getABC(); try { - parser.addScript(src, documentClass, fileName, classPos, scriptIndex); + parser.addScript(src, fileName, classPos, scriptIndex); success = true; } finally { if (!success) { @@ -2601,7 +2600,7 @@ public class ActionScript3Parser { initPlayer(); ABC abc = new ABC(null); ActionScript3Parser parser = new ActionScript3Parser(abc, new ArrayList<>()); - parser.addScript(new String(Helper.readFile(src), Utf8Helper.charset), true, src, classPos, scriptIndex); + parser.addScript(new String(Helper.readFile(src), Utf8Helper.charset), src, classPos, scriptIndex); try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(dst)))) { abc.saveToStream(fos); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java index 0f3b97720..3271011da 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java @@ -258,7 +258,7 @@ public abstract class Trait implements Cloneable, Serializable { if (imp.size() > 1) { //No imports from root package writer.appendNoHilight("import "); - if (!imp.isTopLevel()) { + if (imp.size() > 1) { writer.appendNoHilight(imp.getWithoutLast().toPrintableString(true)); writer.appendNoHilight("."); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java index 3ad0ce0ad..285d957b4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/FFDecAs3ScriptReplacer.java @@ -41,9 +41,6 @@ public class FFDecAs3ScriptReplacer implements As3ScriptReplacerInterface { int oldIndex = pack.scriptIndex; int newIndex = abc.script_info.size(); try { - String documentClass = swf.getDocumentClass(); - boolean isDocumentClass = documentClass != null && documentClass.equals(pack.getClassPath().toString()); - ScriptInfo si = abc.script_info.get(oldIndex); if (pack.isSimple) { si.delete(abc, true); @@ -66,7 +63,7 @@ public class FFDecAs3ScriptReplacer implements As3ScriptReplacerInterface { otherAbcs.remove(abc); abc.script_info.get(oldIndex).delete(abc, true); - ActionScript3Parser.compile(text, abc, otherAbcs, isDocumentClass, scriptName, newClassIndex, oldIndex); + ActionScript3Parser.compile(text, abc, otherAbcs, scriptName, newClassIndex, oldIndex); if (pack.isSimple) { // Move newly added script to its position abc.script_info.set(oldIndex, abc.script_info.get(newIndex)); diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java index 241233ba8..e351eb33e 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java @@ -119,7 +119,7 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase { }); ActionScript3Parser par = new ActionScript3Parser(abc, new ArrayList<>()); HighlightedTextWriter writer = new HighlightedTextWriter(new CodeFormatting(), false); - par.addScript(str, true, "Test.as", 0, 0); + par.addScript(str, "Test.as", 0, 0); abc.script_info.get(0).getPacks(abc, 0, "", new ArrayList<>()).get(0).toSource(writer, abc.script_info.get(0).traits.traits, new ConvertData(), ScriptExportMode.AS, false); return writer.toString(); diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 068db07c4..7d5426d74 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -902,7 +902,7 @@ public class TagTreeContextMenu extends JPopupMenu { + "public class " + IdentifiersDeobfuscation.printIdentifier(true, classSimpleName) + " {" + " }" + "}"; - parser.addScript(script, false, fileName, 0, 0); + parser.addScript(script, fileName, 0, 0); } catch (IOException | InterruptedException | AVM2ParseException | CompilationException ex) { Logger.getLogger(TagTreeContextMenu.class.getName()).log(Level.SEVERE, "Error during script compilation", ex); }