Fixed: #2519 AS1/2 direct editation - generating too large ConstantPool

This commit is contained in:
Jindra Petřík
2025-08-23 21:17:02 +02:00
parent cf55a8b897
commit d086d7bf7f
5 changed files with 57 additions and 9 deletions

View File

@@ -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<String> 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<GraphTargetItem> 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<GraphSourceItem> generateActionList(List<GraphTargetItem> tree, List<String> 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);

View File

@@ -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<String> 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<String> constantPool, String charset) {
public ActionSourceGenerator(int swfVersion, List<String> 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);
}

View File

@@ -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 {