From d086d7bf7f3c1682fc27f345d99c73102f8457e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 23 Aug 2025 21:17:02 +0200 Subject: [PATCH] Fixed: #2519 AS1/2 direct editation - generating too large ConstantPool --- CHANGELOG.md | 1 + .../parser/script/ActionScript2Parser.java | 12 +++-- .../parser/script/ActionSourceGenerator.java | 50 +++++++++++++++++-- .../com/jpexs/helpers/utf8/Utf8Helper.java | 2 +- .../flash/gui/action/ActionPanel.java | 1 + 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4042c2a79..349b76b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ All notable changes to this project will be documented in this file. - [#2517] Loop break detection problems in some cases - [#2519] AS1/2 avoid multi-level loops in cases where possible - [#2522] Hex view - reseting view when mouse over panel bottom +- [#2519] AS1/2 direct editation - generating too large ConstantPool ### Changed - Icon of "Deobfuscation options" menu from pile of pills to medkit diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java index f3dda6233..6f1085777 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java @@ -2206,10 +2206,13 @@ public class ActionScript2Parser { int index = constantPool.indexOf(s); if (index == -1) { - if (ActionConstantPool.calculateSize(constantPool, charset) + ActionConstantPool.calculateSize(s, charset) <= 0xffff) { + int newItemLen = ActionConstantPool.calculateSize(s, charset); + if (constantPool.size() < 0xffff + && constantPoolLength + newItemLen <= 0xffff) { // constant pool is not full constantPool.add(s); index = constantPool.indexOf(s); + constantPoolLength += newItemLen; } } @@ -2223,7 +2226,9 @@ public class ActionScript2Parser { private ActionScriptLexer lexer = null; private List constantPool; - + + private int constantPoolLength = 2; //ActionConstantPool starts with UI16 constant count + /** * Convert a string to a high-level model. * @@ -2244,6 +2249,7 @@ public class ActionScript2Parser { List retTree = new ArrayList<>(); this.constantPool = constantPool; + this.constantPoolLength = ActionConstantPool.calculateSize(constantPool, charset); lexer = new ActionScriptLexer(new StringReader(str)); if (swfVersion >= ActionScriptLexer.SWF_VERSION_CASE_SENSITIVE) { lexer.setCaseSensitiveIdentifiers(true); @@ -2475,7 +2481,7 @@ public class ActionScript2Parser { } private List generateActionList(List tree, List constantPool, boolean secondRun) throws CompilationException { - ActionSourceGenerator gen = new ActionSourceGenerator(swfVersion, constantPool, charset); + ActionSourceGenerator gen = new ActionSourceGenerator(swfVersion, constantPool, constantPoolLength, charset); SourceGeneratorLocalData localData = new SourceGeneratorLocalData(new HashMap<>(), 0, Boolean.FALSE, 0); localData.secondRun = secondRun; return gen.generate(localData, tree); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java index 02b9c9722..60e592d4c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java @@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; import com.jpexs.decompiler.flash.action.swf4.RegisterNumber; import com.jpexs.decompiler.flash.action.swf5.ActionCallFunction; import com.jpexs.decompiler.flash.action.swf5.ActionCallMethod; +import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction; import com.jpexs.decompiler.flash.action.swf5.ActionGetMember; import com.jpexs.decompiler.flash.action.swf5.ActionNewObject; @@ -85,6 +86,8 @@ import java.util.logging.Logger; public class ActionSourceGenerator implements SourceGenerator { private final List constantPool; + + private int constantPoolLength; private final int swfVersion; @@ -97,11 +100,13 @@ public class ActionSourceGenerator implements SourceGenerator { * * @param swfVersion SWF version * @param constantPool Constant pool + * @param constantPoolLength Constant pool length * @param charset Charset */ - public ActionSourceGenerator(int swfVersion, List constantPool, String charset) { + public ActionSourceGenerator(int swfVersion, List constantPool, int constantPoolLength, String charset) { this.constantPool = constantPool; this.swfVersion = swfVersion; + this.constantPoolLength = constantPoolLength; this.charset = charset; } @@ -501,12 +506,29 @@ public class ActionSourceGenerator implements SourceGenerator { * @return Push constant item */ public DirectValueActionItem pushConstTargetItem(String s) { + + //ActionConstantPool was introduced in SWF 5 + if (swfVersion < 5) { + return new DirectValueActionItem(null, null, 0, s, constantPool); + } + int index = constantPool.indexOf(s); if (index == -1) { - constantPool.add(s); - index = constantPool.indexOf(s); + int newItemLen = ActionConstantPool.calculateSize(s, charset); + if (constantPool.size() < 0xffff + && constantPoolLength + newItemLen <= 0xffff) { + // constant pool is not full + constantPool.add(s); + index = constantPool.indexOf(s); + constantPoolLength += newItemLen; + } } - return new DirectValueActionItem(null, null, 0, new ConstantIndex(index), constantPool); + + if (index == -1) { + return new DirectValueActionItem(null, null, 0, s, constantPool); + } + + return new DirectValueActionItem(null, null, 0, new ConstantIndex(index), constantPool); } /** @@ -516,10 +538,28 @@ public class ActionSourceGenerator implements SourceGenerator { * @return Push constant action */ public ActionPush pushConst(String s) { + + if (swfVersion < 5) { + return new ActionPush(s, charset); + } + int index = constantPool.indexOf(s); - if (index == -1) { + if (index == -1) { + + if (constantPool.size() == 0xffff) { + return new ActionPush(s, charset); + } + + int newItemLen = ActionConstantPool.calculateSize(s, charset); + + //constant pool is full + if (constantPoolLength + newItemLen > 0xffff) { + return new ActionPush(s, charset); + } + constantPool.add(s); index = constantPool.indexOf(s); + constantPoolLength += newItemLen; } return new ActionPush(new ConstantIndex(index), charset); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/utf8/Utf8Helper.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/utf8/Utf8Helper.java index 31fce0b4e..f157c1d08 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/helpers/utf8/Utf8Helper.java +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/utf8/Utf8Helper.java @@ -154,7 +154,7 @@ public class Utf8Helper { } public static int getBytesLength(String string, String charset) { - if (charset.toLowerCase().equals(charsetName)) { + if (charset.toUpperCase().equals(charsetName)) { return getBytesLength(string); } try { diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index b35524309..c9eb01325 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -1459,6 +1459,7 @@ public class ActionPanel extends JPanel implements SearchListener