Added: #2636 AS3 QName properties with nonvalid identifiers handled as square brackets

This commit is contained in:
Jindra Petřík
2026-02-17 20:50:57 +01:00
parent 8f248875fb
commit 114f774672
12 changed files with 208 additions and 21 deletions
@@ -28,15 +28,19 @@ import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.StringBuilderTextWriter;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightData;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.helpers.Reference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -156,7 +160,8 @@ public abstract class AVM2Item extends GraphTargetItem {
}
if (empty) {
return propertyName.toString(writer, localData);
((FullMultinameAVM2Item) propertyName).appendTo(writer, localData, false);
return writer;
}
if (propertyName instanceof FullMultinameAVM2Item) {
@@ -177,15 +182,45 @@ public abstract class AVM2Item extends GraphTargetItem {
String operator = nullCondition ? "?." : ".";
if (((FullMultinameAVM2Item) propertyName).name != null) {
if (((FullMultinameAVM2Item) propertyName).namespace != null) {
writer.allowWrapHere().hilightSpecial(operator, HighlightSpecialType.PROPERTY_TYPE, 0, data);
String localName = "";
boolean isAttribute = false;
boolean isValidName = false;
String namespaceSuffix = "";
if (multinameIndex >= 0 && multinameIndex < localData.constantsAvm2.getMultinameCount()) {
Reference<DottedChain> customNsRef = new Reference<>(null);
isAttribute = localData.constantsAvm2.getMultiname(multinameIndex).isAttribute();
localName = localData.constantsAvm2.getMultiname(multinameIndex).getNameAndCustomNamespace(new HashSet<>(), localData.abc, new ArrayList<>(), true, true, customNsRef);
namespaceSuffix = localData.constantsAvm2.getMultiname(multinameIndex).getNamespaceSuffix();
if ("*".equals(localName)) {
isValidName = true;
}
return propertyName.toString(writer, localData);
if (isAttribute) {
isValidName = true;
}
if (!"".equals(namespaceSuffix)) {
isValidName = true;
}
if (IdentifiersDeobfuscation.isValidName(true, localName)) {
isValidName = true;
}
} else {
writer.allowWrapHere().hilightSpecial(operator, HighlightSpecialType.PROPERTY_TYPE, 0, data);
return propertyName.toString(writer, localData);
isValidName = true;
}
if (isValidName) {
if (((FullMultinameAVM2Item) propertyName).name != null) {
if (((FullMultinameAVM2Item) propertyName).namespace != null) {
writer.allowWrapHere().hilightSpecial(operator, HighlightSpecialType.PROPERTY_TYPE, 0, data);
}
} else {
writer.allowWrapHere().hilightSpecial(operator, HighlightSpecialType.PROPERTY_TYPE, 0, data);
}
}
((FullMultinameAVM2Item) propertyName).appendTo(writer, localData, true);
return writer;
} else {
writer.append("[").allowWrapHere();
propertyName.toString(writer, localData);
@@ -29,9 +29,11 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Reference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
@@ -186,14 +188,13 @@ public class FullMultinameAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return appendTo(writer, localData, false);
}
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData, boolean afterDot) throws InterruptedException {
if (namespace != null) {
namespace.toString(writer, localData);
writer.append("::");
} else {
/*Namespace ns = constants.getMultiname(multinameIndex).getNamespace(constants);
if ((ns != null)&&(ns.name_index!=0)) {
ret = hilight(ns.getName(constants) + "::")+ret;
}*/
}
if (name != null) {
writer.append("[");
@@ -207,12 +208,20 @@ public class FullMultinameAVM2Item extends AVM2Item {
AVM2ConstantPool constants = localData.constantsAvm2;
List<DottedChain> fullyQualifiedNames = property ? new ArrayList<>() : localData.fullyQualifiedNames;
if (multinameIndex > 0 && multinameIndex < constants.getMultinameCount()) {
String simpleName = constants.getMultiname(multinameIndex).getName(localData.usedDeobfuscations, localData.abc, constants, fullyQualifiedNames, true, false);
String simpleName = constants.getMultiname(multinameIndex).getName(new HashSet<>(), localData.abc, constants, fullyQualifiedNames, true, false);
if ("*".equals(simpleName)) {
writer.append("*");
} else {
Reference<DottedChain> customNsRef = new Reference<>(null);
String localName = constants.getMultiname(multinameIndex).getNameAndCustomNamespace(localData.usedDeobfuscations, localData.abc, fullyQualifiedNames, false, true, customNsRef);
String localName;
boolean isAttribute = constants.getMultiname(multinameIndex).isAttribute();
String namespaceSuffix = constants.getMultiname(multinameIndex).getNamespaceSuffix();
if (!isAttribute && afterDot && namespaceSuffix.isEmpty()) {
//do not deobfuscate
localName = constants.getMultiname(multinameIndex).getNameAndCustomNamespace(new HashSet<>(), localData.abc, fullyQualifiedNames, true, true, customNsRef);
} else {
localName = constants.getMultiname(multinameIndex).getNameAndCustomNamespace(localData.usedDeobfuscations, localData.abc, fullyQualifiedNames, false, true, customNsRef);
}
DottedChain customNs = customNsRef.getVal();
if (customNs != null) {
String nsname = customNs.getLast();
@@ -221,7 +230,19 @@ public class FullMultinameAVM2Item extends AVM2Item {
writer.appendNoHilight("::");
}
writer.append(localName);
if (!isAttribute && afterDot && namespaceSuffix.isEmpty()) {
if (IdentifiersDeobfuscation.isValidName(true, localName)) {
writer.append(localName);
} else {
if (localName.matches("^0|[1-9][0-9]*$")) {
writer.append("[").append(localName).append("]");
} else {
writer.append("[\"").append(Helper.escapeActionScriptString(localName)).append("\"]");
}
}
} else {
writer.append(localName);
}
}
} else {
writer.append("§§multiname(").append(multinameIndex).append(")");
@@ -32,6 +32,8 @@ public class NulWriter extends GraphTextWriter {
private final Stack<Boolean> stringAddedStack = new Stack<>();
private boolean stringAdded = false;
private int length = 0;
public NulWriter() {
super(new CodeFormatting());
@@ -120,54 +122,63 @@ public class NulWriter extends GraphTextWriter {
@Override
public NulWriter hilightSpecial(String text, HighlightSpecialType type, String specialValue, HighlightData data) {
stringAdded = true;
length += text.length();
return this;
}
@Override
public GraphTextWriter appendWithData(String str, HighlightData data) {
stringAdded = true;
length += str.length();
return this;
}
@Override
public GraphTextWriter append(char value) {
stringAdded = true;
length++;
return this;
}
@Override
public GraphTextWriter append(int value) {
stringAdded = true;
length += ("" + value).length();
return this;
}
@Override
public GraphTextWriter append(long value) {
stringAdded = true;
length += ("" + value).length();
return this;
}
@Override
public NulWriter append(String str) {
stringAdded = true;
length += str.length();
return this;
}
@Override
public NulWriter append(String str, long offset, long fileOffset) {
stringAdded = true;
length += str.length();
return this;
}
@Override
public NulWriter appendNoHilight(int i) {
stringAdded = true;
length += ("" + i).length();
return this;
}
@Override
public NulWriter appendNoHilight(String str) {
stringAdded = true;
length += str.length();
return this;
}
@@ -188,4 +199,9 @@ public class NulWriter extends GraphTextWriter {
stringAdded = stringAddedStack.pop() || result;
return result;
}
@Override
public int getLength() {
return length;
}
}