mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 19:08:19 +00:00
Fixed #116 AS3 Cyclic typenames protection
This commit is contained in:
@@ -729,6 +729,7 @@ public class ABC implements Openable {
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
constants.checkCyclicTypeNames();
|
||||
|
||||
ais.endDumpLevel(); // cpool_info
|
||||
|
||||
|
||||
@@ -867,4 +867,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void checkCyclicTypeNames() {
|
||||
for (int i = 0; i < constant_multiname.size(); i++) {
|
||||
Multiname.checkTypeNameCyclic(this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,11 +99,11 @@ public class InstanceInfo {
|
||||
CharacterTag ct = abc.getSwf().getCharacterByClass(className);
|
||||
if (ct != null) {
|
||||
if (ct instanceof DefineBinaryDataTag) {
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + ct.getCharacterExportFileName() + ".bin\", mimeType=\"application/octet-stream\")]").newLine();
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ".bin\", mimeType=\"application/octet-stream\")]").newLine();
|
||||
}
|
||||
if (ct instanceof ImageTag) {
|
||||
ImageTag it = (ImageTag) ct;
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + ct.getCharacterExportFileName() + ((ImageTag) ct).getImageFormat().getExtension() + "\")]").newLine();
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ((ImageTag) ct).getImageFormat().getExtension() + "\")]").newLine();
|
||||
}
|
||||
if (ct instanceof DefineSpriteTag) {
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + "assets.swf\", symbol=\"" + Helper.escapeActionScriptString(className) + "\")]").newLine();
|
||||
@@ -111,7 +111,7 @@ public class InstanceInfo {
|
||||
if (ct instanceof DefineSoundTag) {
|
||||
//should be mp3, otherwise it won't work. Should we convert this?
|
||||
DefineSoundTag st = (DefineSoundTag) ct;
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + ct.getCharacterExportFileName() + "." + (st.getSoundFormat().formatId == SoundFormat.FORMAT_MP3 ? "mp3" : "wav") + "\")]").newLine();
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + "." + (st.getSoundFormat().formatId == SoundFormat.FORMAT_MP3 ? "mp3" : "wav") + "\")]").newLine();
|
||||
}
|
||||
if (ct instanceof FontTag) {
|
||||
FontTag ft = (FontTag) ct;
|
||||
@@ -125,7 +125,7 @@ public class InstanceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + ct.getCharacterExportFileName() + ".ttf\",").newLine();
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ".ttf\",").newLine();
|
||||
writer.appendNoHilight("fontName=\"" + Helper.escapeActionScriptString(ft.getFontNameIntag()) + "\",").newLine();
|
||||
writer.appendNoHilight("fontFamily=\"" + Helper.escapeActionScriptString(ft.getFontName())+ "\",").newLine();
|
||||
writer.appendNoHilight("mimeType=\"application/x-font\",").newLine();
|
||||
@@ -174,7 +174,7 @@ public class InstanceInfo {
|
||||
|
||||
if (ct instanceof DefineFont4Tag) {
|
||||
DefineFont4Tag ft4 = (DefineFont4Tag)ct;
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + ct.getCharacterExportFileName() + ".cff\",").newLine();
|
||||
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ".cff\",").newLine();
|
||||
writer.appendNoHilight("fontName=\"" + Helper.escapeActionScriptString(ft4.fontName) + "\",").newLine();
|
||||
writer.appendNoHilight("mimeType=\"application/x-font\",").newLine();
|
||||
writer.appendNoHilight("fontWeight=\"" + (ft4.fontFlagsBold ? "bold" : "normal") + "\",").newLine();
|
||||
|
||||
@@ -80,6 +80,9 @@ public class Multiname {
|
||||
@Internal
|
||||
private boolean displayNamespace = false;
|
||||
|
||||
@Internal
|
||||
private boolean cyclic = false;
|
||||
|
||||
public String getNamespaceSuffix() {
|
||||
if (displayNamespace) {
|
||||
return "#" + namespace_index;
|
||||
@@ -157,6 +160,39 @@ public class Multiname {
|
||||
return new Multiname(TYPENAME, 0, 0, 0, qname_index, params);
|
||||
}
|
||||
|
||||
public static void checkTypeNameCyclic(AVM2ConstantPool constants, int name_index) {
|
||||
Set<Integer> visited = new HashSet<>();
|
||||
if (name_index >= constants.getMultinameCount()) {
|
||||
return;
|
||||
}
|
||||
Multiname m = constants.getMultiname(name_index);
|
||||
if (m != null) {
|
||||
m.cyclic = checkCyclicTypeNameSub(constants, name_index, visited);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkCyclicTypeNameSub(AVM2ConstantPool constants, int name_index, Set<Integer> visited) {
|
||||
if (name_index >= constants.getMultinameCount()) {
|
||||
return false;
|
||||
}
|
||||
Multiname m = constants.getMultiname(name_index);
|
||||
if (m != null && m.kind == Multiname.TYPENAME) {
|
||||
if (visited.contains(name_index)) {
|
||||
return true;
|
||||
}
|
||||
visited.add(name_index);
|
||||
if (checkCyclicTypeNameSub(constants, m.qname_index, visited)) {
|
||||
return true;
|
||||
}
|
||||
for (int p : m.params) {
|
||||
if (checkCyclicTypeNameSub(constants, p, visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAttribute() {
|
||||
if (kind == QNAMEA) {
|
||||
return true;
|
||||
@@ -272,16 +308,15 @@ public class Multiname {
|
||||
String versionAdd = "";
|
||||
if (name != null && name.length() > 0) {
|
||||
char lastChar = name.charAt(name.length() - 1);
|
||||
|
||||
|
||||
if (lastChar >= Namespace.MIN_API_MARK && lastChar <= Namespace.MAX_API_MARK) {
|
||||
name = name.substring(0, name.length() - 1);
|
||||
versionAdd = String.format("\\u%04x", (int) lastChar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return constants.getNamespace(index).getKindStr() + "(" + (name == null ? "null" : "\"" +
|
||||
Helper.escapePCodeString(name) + versionAdd
|
||||
|
||||
return constants.getNamespace(index).getKindStr() + "(" + (name == null ? "null" : "\""
|
||||
+ Helper.escapePCodeString(name) + versionAdd
|
||||
+ "\"") + (sub > 0 ? ",\"" + sub + "\"" : "") + ")";
|
||||
}
|
||||
|
||||
@@ -331,6 +366,9 @@ public class Multiname {
|
||||
case MULTINAMELA:
|
||||
return getKindStr() + "(" + namespaceSetToString(constants, namespace_set_index) + ")";
|
||||
case TYPENAME:
|
||||
if (cyclic) {
|
||||
return "CyclicTypeName";
|
||||
}
|
||||
String tret = getKindStr() + "(";
|
||||
tret += multinameToString(constants, qname_index, fullyQualifiedNames);
|
||||
tret += "<";
|
||||
@@ -350,8 +388,8 @@ public class Multiname {
|
||||
}
|
||||
|
||||
private String typeNameToStr(AVM2ConstantPool constants, List<DottedChain> fullyQualifiedNames, boolean dontDeobfuscate, boolean withSuffix) {
|
||||
if (constants.getMultiname(qname_index).name_index == name_index) {
|
||||
return "ambiguousTypeName";
|
||||
if (cyclic) {
|
||||
return "§§cyclic_typename()";
|
||||
}
|
||||
StringBuilder typeNameStr = new StringBuilder();
|
||||
typeNameStr.append(constants.getMultiname(qname_index).getName(constants, fullyQualifiedNames, dontDeobfuscate, withSuffix));
|
||||
@@ -389,7 +427,7 @@ public class Multiname {
|
||||
if (nskind == Namespace.KIND_NAMESPACE || nskind == Namespace.KIND_PACKAGE_INTERNAL) {
|
||||
DottedChain dc = abc.findCustomNsOfMultiname(this);
|
||||
String nsname = dc != null ? dc.getLast() : null;
|
||||
|
||||
|
||||
if (nsname != null && !"AS3".equals(nsname)) {
|
||||
String identifier = dontDeobfuscate ? nsname : IdentifiersDeobfuscation.printIdentifier(true, nsname);
|
||||
if (identifier != null && !identifier.isEmpty()) {
|
||||
@@ -432,9 +470,9 @@ public class Multiname {
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
|
||||
DottedChain nsName = getSimpleNamespaceName(constants);
|
||||
if (nsName == null) {
|
||||
if (nsName == null) {
|
||||
Namespace ns = getNamespace(constants);
|
||||
if (ns == null) {
|
||||
NamespaceSet nss = getNamespaceSet(constants);
|
||||
@@ -453,7 +491,7 @@ public class Multiname {
|
||||
if (nsName != null) {
|
||||
ret = nsName.add(name, withSuffix ? getNamespaceSuffix() : "");
|
||||
} else {
|
||||
ret = new DottedChain(new String[]{name}, new String[]{withSuffix ? getNamespaceSuffix() : ""});
|
||||
ret = new DottedChain(new String[]{name}, new String[]{withSuffix ? getNamespaceSuffix() : ""});
|
||||
}
|
||||
constants.cacheMultinameWithNamespace(this, ret);
|
||||
return ret;
|
||||
@@ -466,19 +504,20 @@ public class Multiname {
|
||||
return constants.getNamespace(namespace_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets simple namespace name as dottedchain. Ignores swf api versioning.
|
||||
*
|
||||
* @param constants
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
public DottedChain getSimpleNamespaceName(AVM2ConstantPool constants) {
|
||||
public DottedChain getSimpleNamespaceName(AVM2ConstantPool constants) {
|
||||
if (hasOwnNamespace()) {
|
||||
if (namespace_index == 0 || namespace_index == -1) {
|
||||
return DottedChain.EMPTY;
|
||||
}
|
||||
return getNamespace(constants).getName(constants);
|
||||
}
|
||||
}
|
||||
if (hasOwnNamespaceSet()) {
|
||||
NamespaceSet nss = getNamespaceSet(constants);
|
||||
if (nss == null) {
|
||||
@@ -488,11 +527,12 @@ public class Multiname {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets simplpe namespace kind. Ignores swf api versioning.
|
||||
*
|
||||
* @param constants
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
public int getSimpleNamespaceKind(AVM2ConstantPool constants) {
|
||||
if (hasOwnNamespace()) {
|
||||
@@ -500,7 +540,7 @@ public class Multiname {
|
||||
return 0;
|
||||
}
|
||||
return getNamespace(constants).kind;
|
||||
}
|
||||
}
|
||||
if (hasOwnNamespaceSet()) {
|
||||
NamespaceSet nss = getNamespaceSet(constants);
|
||||
if (nss == null) {
|
||||
@@ -510,7 +550,7 @@ public class Multiname {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public List<Integer> getApiVersions(AVM2ConstantPool constants) {
|
||||
if (hasOwnNamespace()) {
|
||||
return new ArrayList<>();
|
||||
@@ -520,7 +560,7 @@ public class Multiname {
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
public boolean isApiVersioned(AVM2ConstantPool constants) {
|
||||
if (hasOwnNamespace()) {
|
||||
return false;
|
||||
@@ -656,4 +696,8 @@ public class Multiname {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isCyclic() {
|
||||
return cyclic;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user