Fixed: AS1/2 actions must use SWF charset when writing its length

This commit is contained in:
Jindra Petřík
2025-08-19 18:14:41 +02:00
parent a84cdd3682
commit 1c88c0304b
9 changed files with 27 additions and 13 deletions
@@ -145,7 +145,7 @@ public abstract class Action implements GraphSourceItem {
/**
* Charset - SWFs version 5 and lower do not use UTF-8
*/
private String charset;
protected String charset;
/**
* Names of ActionScript properties
@@ -538,7 +538,7 @@ public abstract class Action implements GraphSourceItem {
ActionConstantPool cPool = (ActionConstantPool) action;
List<String> constantPool = constantPools.get(poolIdx);
int size = ActionConstantPool.calculateSize(constantPool);
int size = ActionConstantPool.calculateSize(constantPool, action.getCharset());
if (size > 0xffff && tryInline) {
for (int i = 0; i < constantPool.size(); i++) {
int refCount = actions.getConstantPoolIndexReferenceCount(i);
@@ -548,7 +548,7 @@ public abstract class Action implements GraphSourceItem {
}
}
size = ActionConstantPool.calculateSize(constantPool);
size = ActionConstantPool.calculateSize(constantPool, action.getCharset());
}
if (size > 0xffff) {
@@ -2204,7 +2204,7 @@ public class ActionScript2Parser {
int index = constantPool.indexOf(s);
if (index == -1) {
if (ActionConstantPool.calculateSize(constantPool) + ActionConstantPool.calculateSize(s) <= 0xffff) {
if (ActionConstantPool.calculateSize(constantPool, charset) + ActionConstantPool.calculateSize(s, charset) <= 0xffff) {
// constant pool is not full
constantPool.add(s);
index = constantPool.indexOf(s);
@@ -121,7 +121,7 @@ public class ActionGetURL extends Action {
*/
@Override
protected int getContentBytesLength() {
return Utf8Helper.getBytesLength(urlString) + Utf8Helper.getBytesLength(targetString) + 2;
return Utf8Helper.getBytesLength(urlString, charset) + Utf8Helper.getBytesLength(targetString, charset) + 2;
}
@Override
@@ -98,7 +98,7 @@ public class ActionGoToLabel extends Action {
*/
@Override
protected int getContentBytesLength() {
return Utf8Helper.getBytesLength(label) + 1;
return Utf8Helper.getBytesLength(label, charset) + 1;
}
/**
@@ -104,7 +104,7 @@ public class ActionSetTarget extends Action {
*/
@Override
protected int getContentBytesLength() {
return Utf8Helper.getBytesLength(targetName) + 1;
return Utf8Helper.getBytesLength(targetName, charset) + 1;
}
/**
@@ -216,7 +216,7 @@ public class ActionPush extends Action {
int res = 0;
for (Object o : vals) {
if (o instanceof String) {
res += Utf8Helper.getBytesLength((String) o) + 2;
res += Utf8Helper.getBytesLength((String) o, charset) + 2;
} else if (o instanceof Float) {
res += 5;
} else if (o == Null.INSTANCE) {
@@ -125,29 +125,31 @@ public class ActionConstantPool extends Action {
*/
@Override
protected int getContentBytesLength() {
return calculateSize(constantPool);
return calculateSize(constantPool, charset);
}
/**
* Calculates size of string converted to bytes
*
* @param str String
* @param charset Charset
* @return Size
*/
public static int calculateSize(String str) {
return Utf8Helper.getBytesLength(str) + 1;
public static int calculateSize(String str, String charset) {
return Utf8Helper.getBytesLength(str, charset) + 1;
}
/**
* Calculates the size of the action converted to bytes
*
* @param strings Strings
* @param charset Charset
* @return Size
*/
public static int calculateSize(List<String> strings) {
public static int calculateSize(List<String> strings, String charset) {
int res = 2;
for (String s : strings) {
res += Utf8Helper.getBytesLength(s) + 1;
res += Utf8Helper.getBytesLength(s, charset) + 1;
}
return res;