Better namespace handling

This commit is contained in:
Jindra Petřík
2021-02-02 19:27:29 +01:00
parent c7b42da8c1
commit c985e3e402
19 changed files with 152 additions and 70 deletions

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc;
import com.jpexs.decompiler.flash.EndOfStreamException;
@@ -2070,4 +2071,28 @@ public class ABC {
}
return newTrait;
}
public DottedChain findCustomNs(int link_ns_index) {
String nsname;
if (link_ns_index <= 0) {
return null;
}
Namespace ns = constants.getNamespace(link_ns_index);
if (ns.kind != Namespace.KIND_NAMESPACE) {
return null;
}
String name = constants.getString(ns.name_index);
for (ABCContainerTag abcTag : getAbcTags()) {
DottedChain dc = abcTag.getABC().nsValueToName(name);
nsname = dc.getLast();
if (nsname == null) {
continue;
}
if (!nsname.isEmpty()) {
return dc;
}
}
return null;
}
}

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -50,7 +51,7 @@ public class CodeStats {
if (stats.stackpos > ms) {
ms = stats.stackpos;
}
}
writer.appendNoHilight(i + ":" + stats.stackpos + (deltastack >= 0 ? "+" + deltastack : deltastack) + "," + stats.scopepos + " " + stats.ins.toString(writer, LocalData.create(abc, null, fullyQualifiedNames))).newLine();
i++;
}
return writer;

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -106,8 +107,8 @@ public class ConstructIns extends InstructionDefinition {
FullMultinameAVM2Item fptXmlMult = (FullMultinameAVM2Item) fpt.propertyName;
FullMultinameAVM2Item gptXmlMult = (FullMultinameAVM2Item) gpt.propertyName;
isXML = fptXmlMult.isXML(localData.getConstants(), localData.localRegNames, localData.fullyQualifiedNames)
isXML = fptXmlMult.isXML(localData.abc, localData.localRegNames, localData.fullyQualifiedNames)
&& gptXmlMult.isXML(localData.abc, localData.localRegNames, localData.fullyQualifiedNames);
}
}
if (obj instanceof GetLexAVM2Item) {
@@ -134,8 +135,8 @@ public class ConstructIns extends InstructionDefinition {
FullMultinameAVM2Item fptRegExpMult = (FullMultinameAVM2Item) fpt.propertyName;
FullMultinameAVM2Item gptRegExpMult = (FullMultinameAVM2Item) gpt.propertyName;
isRegExp = fptRegExpMult.isTopLevel("RegExp", localData.getConstants(), localData.localRegNames, localData.fullyQualifiedNames)
isRegExp = fptRegExpMult.isTopLevel("RegExp", localData.abc, localData.localRegNames, localData.fullyQualifiedNames)
&& gptRegExpMult.isTopLevel("RegExp", localData.abc, localData.localRegNames, localData.fullyQualifiedNames);
}
}
if (obj instanceof GetLexAVM2Item) {

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -73,7 +74,7 @@ public class ConstructPropIns extends InstructionDefinition {
multiname.property = false; //can be type
}
if (multiname.isXML(localData.abc, localData.localRegNames, localData.fullyQualifiedNames)) {
if (args.size() == 1) {
GraphTargetItem arg = args.get(0);
List<GraphTargetItem> xmlLines = new ArrayList<>();
@@ -84,7 +85,7 @@ public class ConstructPropIns extends InstructionDefinition {
}
}//
boolean isRegExp = false;
boolean isRegExp = false;
if (multiname.isTopLevel("RegExp", localData.abc, localData.localRegNames, localData.fullyQualifiedNames)) {
isRegExp = true;
}
if (isRegExp && (args.size() >= 1) && (args.get(0) instanceof StringAVM2Item) && (args.size() == 1 || (args.size() == 2 && args.get(1) instanceof StringAVM2Item))) {

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -42,7 +43,7 @@ public class NewClassIns extends InstructionDefinition {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) throws InterruptedException {
int clsIndex = ins.operands[0];
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
stack.pop().toString(writer, LocalData.create(localData.abc, localData.localRegNames, localData.fullyQualifiedNames));
String baseType = writer.toString();
ABC abc = localData.abc;
stack.push(new UnparsedAVM2Item(ins, localData.lineStartInstruction, "new " + abc.constants.getMultiname(abc.instance_info.get(clsIndex).name_index).getName(localData.getConstants(), localData.fullyQualifiedNames, false, true) + ".class extends " + baseType));

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.instructions.other;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -68,7 +69,7 @@ public class SetSuperIns extends InstructionDefinition implements SetTypeIns {
int multinameIndex = ins.operands[0];
String multiname = resolveMultinameNoPop(1, stack, abc.constants, multinameIndex, ins, fullyQualifiedNames);
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
stack.get(1 + resolvedCount(abc.constants, multinameIndex)).toString(writer, LocalData.create(abc, localRegNames, fullyQualifiedNames));
String obj = writer.toString();
return obj + ".super." + multiname;
}

View File

@@ -12,9 +12,11 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
@@ -85,27 +87,27 @@ public class FullMultinameAVM2Item extends AVM2Item {
return (name != null) || (namespace != null);
}
public boolean isTopLevel(String tname, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
String cname;
if (name != null) {
if (name != null) {
cname = name.toString(LocalData.create(abc, localRegNames, fullyQualifiedNames));
} else {
} else {
cname = (abc.constants.getMultiname(multinameIndex).getName(abc.constants, fullyQualifiedNames, true, true));
}
String cns = "";
if (namespace != null) {
if (namespace != null) {
cns = namespace.toString(LocalData.create(abc, localRegNames, fullyQualifiedNames));
} else {
} else {
Namespace ns = abc.constants.getMultiname(multinameIndex).getNamespace(abc.constants);
if ((ns != null) && (ns.name_index != 0)) {
if ((ns != null) && (ns.name_index != 0)) {
cns = ns.getName(abc.constants).toPrintableString(true);
}
}
return cname.equals(tname) && cns.isEmpty();
}
public boolean isXML(AVM2ConstantPool constants, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
public boolean isXML(ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
return isTopLevel("XML", abc, localRegNames, fullyQualifiedNames);
}
@Override

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
@@ -47,9 +48,9 @@ public class GetLexAVM2Item extends AVM2Item implements SimpleValue {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) {
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) {
String localName = propertyName.getNameWithCustomNamespace(localData.abc, localData.fullyQualifiedNames, false, true);
getSrcData().localName = localName;
getSrcData().localName = localName;
return writer.append(propertyName.getNameWithCustomNamespace(localData.abc, localData.fullyQualifiedNames, false, true));
}
@Override

View File

@@ -12,15 +12,20 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.helpers.Helper;
/**
*
@@ -38,15 +43,30 @@ public class NameSpaceAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) {
if (namespaceIndex == 0) {
if (namespaceIndex == 0) {
return writer.append("*"); //?
}
AVM2ConstantPool constants = localData.constantsAvm2;
AVM2ConstantPool constants = localData.constantsAvm2;
DottedChain dc = localData.abc.findCustomNs(namespaceIndex);
String nsname = dc != null ? dc.getLast() : null;
if (nsname != null) {
String identifier = IdentifiersDeobfuscation.printIdentifier(true, nsname);
if (identifier != null && !identifier.isEmpty()) {
writer.append(identifier);
return writer;
}
}
writer.append("new Namespace").spaceBeforeCallParenthesies(1).append("(");
writer.append("\"").append(Helper.escapeActionScriptString(constants.getNamespace(namespaceIndex).getRawName(constants))).append("\""); //assume not null name
writer.append(")");
return writer;
}
@Override
public GraphTargetItem returnType() {
public GraphTargetItem returnType() {
return new TypeItem("Namespace");
}
@Override

View File

@@ -303,7 +303,7 @@ public final class MethodBody implements Cloneable {
convertedItems1 = converted.getCode().toGraphTargetItems(convertData.thisHasDefaultToPrimitive, convertData, path, methodIndex, isStatic, scriptIndex, classIndex, abc, converted, localRegNames, scopeStack, initializerType, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<>(), converted.getCode().visitCode(converted));
}
try (Statistics s = new Statistics("Graph.graphToString")) {
Graph.graphToString(convertedItems1, writer, LocalData.create(abc.constants, localRegNames, fullyQualifiedNames));
Graph.graphToString(convertedItems1, writer, LocalData.create(abc, localRegNames, fullyQualifiedNames));
}
convertedItems = convertedItems1;
}
@@ -357,7 +357,7 @@ public final class MethodBody implements Cloneable {
writer.appendNoHilight(this.method_info);
writer.newLine();
}
Graph.graphToString(convertedItems, writer, LocalData.create(abc.constants, localRegNames, fullyQualifiedNames));
Graph.graphToString(convertedItems, writer, LocalData.create(abc, localRegNames, fullyQualifiedNames));
//writer.endMethod();
} else if (convertException instanceof TimeoutException) {
// exception was logged in convert method

View File

@@ -12,10 +12,12 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.graph.DottedChain;
@@ -349,6 +351,40 @@ public class Multiname {
return typeNameStr.toString();
}
public String getNameWithCustomNamespace(ABC abc, List<DottedChain> fullyQualifiedNames, boolean dontDeobfuscate, boolean withSuffix) {
if (kind == TYPENAME) {
return typeNameToStr(abc.constants, fullyQualifiedNames, dontDeobfuscate, withSuffix);
}
if (name_index == -1) {
return "";
}
if (name_index == 0) {
return isAttribute() ? "@*" : "*";
} else {
String name = abc.constants.getString(name_index);
if (namespace_index > 0 && getNamespace(abc.constants).kind == Namespace.KIND_NAMESPACE) {
DottedChain dc = abc.findCustomNs(namespace_index);
String nsname = dc != null ? dc.getLast() : null;
if (nsname != null) {
String identifier = dontDeobfuscate ? nsname : IdentifiersDeobfuscation.printIdentifier(true, nsname);
if (identifier != null && !identifier.isEmpty()) {
return nsname + "::" + name;
}
} else {
//???
}
}
if (fullyQualifiedNames != null && fullyQualifiedNames.contains(DottedChain.parseWithSuffix(name))) {
DottedChain dc = getNameWithNamespace(abc.constants, withSuffix);
return dontDeobfuscate ? dc.toRawString() : dc.toPrintableString(true);
}
return (isAttribute() ? "@" : "") + (dontDeobfuscate ? name : IdentifiersDeobfuscation.printIdentifier(true, name)) + (withSuffix ? getNamespaceSuffix() : "");
}
}
public String getName(AVM2ConstantPool constants, List<DottedChain> fullyQualifiedNames, boolean dontDeobfuscate, boolean withSuffix) {
if (kind == TYPENAME) {
return typeNameToStr(constants, fullyQualifiedNames, dontDeobfuscate, withSuffix);

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -125,6 +126,14 @@ public class Namespace {
return constants.getDottedChain(name_index);
}
public String getRawName(AVM2ConstantPool constants) {
if (name_index == 0 || name_index == -1) {
return ""; //??
}
return constants.getString(name_index);
}
public boolean hasName(String name, AVM2ConstantPool constants) {
if (name == null && name_index == 0) {
return true;

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types.traits;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -304,37 +305,13 @@ public abstract class Trait implements Cloneable, Serializable {
return writer;
}
protected final DottedChain findCustomNs(int link_ns_index, ABC abc) {
String nsname;
if (link_ns_index <= 0) {
return null;
}
Namespace ns = abc.constants.getNamespace(link_ns_index);
if (ns.kind != Namespace.KIND_NAMESPACE) {
return null;
}
String name = abc.constants.getString(ns.name_index);
for (ABCContainerTag abcTag : abc.getAbcTags()) {
DottedChain dc = abcTag.getABC().nsValueToName(name);
nsname = dc.getLast();
if (nsname == null) {
continue;
}
if (!nsname.isEmpty()) {
return dc;
}
}
return null;
}
public final GraphTextWriter getModifiers(ABC abc, boolean isStatic, GraphTextWriter writer) {
if ((kindFlags & ATTR_Override) > 0) {
writer.appendNoHilight("override ");
}
Multiname m = getName(abc);
if (m != null) {
if (m != null) {
DottedChain dc = abc.findCustomNs(m.namespace_index);
String nsname = dc != null ? dc.getLast() : null;
Namespace ns = m.getNamespace(abc.constants);

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types.traits;
import com.jpexs.decompiler.flash.abc.ABC;

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types.traits;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -120,7 +121,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
writer.newLine();
}
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
assignment.value.toString(writer, LocalData.create(abc, new HashMap<>(), fullyQualifiedNames));
}
writer.endMethod();
writer.endTrait();
@@ -160,7 +161,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
if (convertData.assignedValues.containsKey(this)) {
GraphTargetItem val = convertData.assignedValues.get(this).value;
if (val instanceof NewFunctionAVM2Item) {
if (val instanceof NewFunctionAVM2Item) {
return val.toString(writer, LocalData.create(abc, new HashMap<>(), fullyQualifiedNames));
}
}
getNameStr(writer, abc, fullyQualifiedNames);

View File

@@ -12,9 +12,11 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.graph.model;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.action.model.ConstantPool;
import com.jpexs.decompiler.graph.DottedChain;
@@ -37,15 +39,18 @@ public class LocalData {
public List<DottedChain> fullyQualifiedNames;
public ABC abc;
public static LocalData create(ConstantPool constants) {
LocalData localData = new LocalData();
localData.constants = constants;
return localData;
}
public static LocalData create(ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) {
LocalData localData = new LocalData();
LocalData localData = new LocalData();
localData.abc = abc;
localData.constantsAvm2 = abc.constants;
localData.localRegNames = localRegNames;
localData.fullyQualifiedNames = fullyQualifiedNames;
return localData;