mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 11:10:50 +00:00
Issue #1279 show duplicate trait names with hash suffix
Fixed editing const/slot Namespace testdata
This commit is contained in:
@@ -692,19 +692,9 @@ public class ABC {
|
||||
SWFDecompilerPlugin.fireMethodBodyParsed(this, mb, swf);
|
||||
}
|
||||
|
||||
markSameContextMultinames();
|
||||
getMethodIndexing();
|
||||
|
||||
/*for(int i=0;i<script_count;i++){
|
||||
MethodBody bod=bodies.get(bodyIdxFromMethodIdx.get(script_info.get(i).init_index));
|
||||
GraphTextWriter t=new HighlightedTextWriter(Configuration.getCodeFormatting(),false);
|
||||
try {
|
||||
bod.toString("script", ScriptExportMode.PCODE, this, null, constants, method_info, t, new ArrayList<>());
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
System.out.println(""+t.toString());
|
||||
}
|
||||
//System.exit(0);*/
|
||||
SWFDecompilerPlugin.fireAbcParsed(this, swf);
|
||||
}
|
||||
|
||||
@@ -1119,6 +1109,60 @@ public class ABC {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void markSameContextMultinames() {
|
||||
|
||||
//Reset
|
||||
for (int multinameIndex = 1; multinameIndex < constants.getMultinameCount(); multinameIndex++) {
|
||||
constants.getMultiname(multinameIndex).setDisplayNamespace(false);
|
||||
}
|
||||
|
||||
//group qnames with same name
|
||||
Map<String, List<Integer>> nameToQNameIndices = new HashMap<>();
|
||||
for (int multinameIndex = 1; multinameIndex < constants.getMultinameCount(); multinameIndex++) {
|
||||
Multiname m = constants.getMultiname(multinameIndex);
|
||||
if (m.kind == Multiname.QNAME || m.kind == Multiname.QNAMEA) {
|
||||
String name = m.getName(constants, new ArrayList<>(), true);
|
||||
if (!nameToQNameIndices.containsKey(name)) {
|
||||
nameToQNameIndices.put(name, new ArrayList<>());
|
||||
}
|
||||
nameToQNameIndices.get(name).add(multinameIndex);
|
||||
}
|
||||
}
|
||||
Set<MultinameUsage> collidingUsages = new HashSet<>();
|
||||
|
||||
//find context of names with count 2 or more
|
||||
for (String name : nameToQNameIndices.keySet()) {
|
||||
List<Integer> multinameIndices = nameToQNameIndices.get(name);
|
||||
if (multinameIndices.size() > 1) {
|
||||
List<List<MultinameUsage>> allUsages = new ArrayList<>();
|
||||
for (int multinameIndex : multinameIndices) {
|
||||
List<MultinameUsage> usages = findMultinameUsage(multinameIndex);
|
||||
for (MultinameUsage usage : usages) {
|
||||
for (List<MultinameUsage> prevUsages : allUsages) {
|
||||
for (MultinameUsage prevUsage : prevUsages) {
|
||||
if (prevUsage.collides(usage)) {
|
||||
collidingUsages.add(usage);
|
||||
collidingUsages.add(prevUsage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
allUsages.add(usages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<Integer> collidingMultinameIndices = new HashSet<>();
|
||||
|
||||
for (MultinameUsage col : collidingUsages) {
|
||||
collidingMultinameIndices.add(col.multinameIndex);
|
||||
}
|
||||
|
||||
for (int multinameIndex : collidingMultinameIndices) {
|
||||
constants.getMultiname(multinameIndex).setDisplayNamespace(true);
|
||||
}
|
||||
}
|
||||
|
||||
public List<MultinameUsage> findMultinameUsage(int multinameIndex) {
|
||||
List<MultinameUsage> ret = new ArrayList<>();
|
||||
if (multinameIndex == 0) {
|
||||
|
||||
@@ -34,8 +34,10 @@ import com.jpexs.helpers.HashArrayList;
|
||||
import com.jpexs.helpers.utf8.Utf8PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
@@ -1129,6 +1129,7 @@ public class ASM3Parser {
|
||||
info.optional[i] = optional.get(i);
|
||||
}
|
||||
}
|
||||
abc.markSameContextMultinames();
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
+1911
-1885
File diff suppressed because it is too large
Load Diff
+1949
-2179
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -35,5 +35,6 @@ public enum SymbolGroup {
|
||||
//GLOBALFUNC,
|
||||
GLOBALCONST,
|
||||
PREPROCESSOR,
|
||||
REGEXP
|
||||
REGEXP,
|
||||
NAMESPACESUFFIX
|
||||
}
|
||||
|
||||
+2
-1
@@ -207,7 +207,8 @@ public enum SymbolType {
|
||||
DESCENDANTS(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NATIVE,
|
||||
PREPROCESSOR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
REGEXP(GraphTargetItem.PRECEDENCE_PRIMARY, false);
|
||||
REGEXP(GraphTargetItem.PRECEDENCE_PRIMARY, false),
|
||||
NAMESPACESUFFIX;
|
||||
|
||||
private int precedence = GraphTargetItem.NOPRECEDENCE;
|
||||
|
||||
|
||||
@@ -73,6 +73,13 @@ public class Multiname {
|
||||
@Internal
|
||||
public boolean deleted;
|
||||
|
||||
@Internal
|
||||
private boolean displayNamespace = false;
|
||||
|
||||
public void setDisplayNamespace(boolean displayNamespace) {
|
||||
this.displayNamespace = displayNamespace;
|
||||
}
|
||||
|
||||
private boolean validType() {
|
||||
boolean cnt = false;
|
||||
for (int i = 0; i < multinameKinds.length; i++) {
|
||||
@@ -335,11 +342,15 @@ public class Multiname {
|
||||
return isAttribute() ? "@*" : "*";
|
||||
} else {
|
||||
String name = constants.getString(name_index);
|
||||
String nssuffix = "";
|
||||
if (displayNamespace) {
|
||||
nssuffix += "#" + namespace_index;
|
||||
}
|
||||
if (fullyQualifiedNames != null && fullyQualifiedNames.contains(DottedChain.parse(name))) {
|
||||
DottedChain dc = getNameWithNamespace(constants);
|
||||
return raw ? dc.toRawString() : dc.toPrintableString(true);
|
||||
}
|
||||
return (isAttribute() ? "@" : "") + (raw ? name : IdentifiersDeobfuscation.printIdentifier(true, name));
|
||||
return (isAttribute() ? "@" : "") + (raw ? name : IdentifiersDeobfuscation.printIdentifier(true, name) + nssuffix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-2
@@ -22,14 +22,31 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ClassNameMultinameUsage extends InsideClassMultinameUsage implements DefinitionUsage {
|
||||
public class ClassNameMultinameUsage extends MultinameUsage implements DefinitionUsage, InsideClassMultinameUsageInterface {
|
||||
|
||||
private int classIndex;
|
||||
|
||||
public ClassNameMultinameUsage(ABC abc, int multinameIndex, int classIndex) {
|
||||
super(abc, multinameIndex, classIndex);
|
||||
super(abc, multinameIndex);
|
||||
this.classIndex = classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClassIndex() {
|
||||
return classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "class " + abc.constants.getMultiname(abc.instance_info.get(classIndex).name_index).getNameWithNamespace(abc.constants).toPrintableString(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
if (other instanceof ClassNameMultinameUsage) {
|
||||
return sameMultinameName(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public abstract class ConstVarMultinameUsage extends TraitMultinameUsage {
|
||||
} catch (InterruptedException ex) {
|
||||
// ignore
|
||||
}
|
||||
return writer.toString();
|
||||
return writer.toString().trim();
|
||||
}
|
||||
|
||||
public int getTraitIndex() {
|
||||
|
||||
+14
@@ -33,4 +33,18 @@ public class ConstVarNameMultinameUsage extends ConstVarMultinameUsage implement
|
||||
public String toString() {
|
||||
return super.toString() + " name";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
if ((other instanceof ConstVarNameMultinameUsage) || (other instanceof MethodNameMultinameUsage)) {
|
||||
TraitMultinameUsage otherTrait = (TraitMultinameUsage) other;
|
||||
if (otherTrait.classIndex == classIndex && otherTrait.traitsType == traitsType) {
|
||||
if (other.sameMultinameName(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
@@ -33,4 +33,10 @@ public class ConstVarTypeMultinameUsage extends ConstVarMultinameUsage {
|
||||
public String toString() {
|
||||
return super.toString() + " type";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-2
@@ -22,14 +22,28 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ExtendsMultinameUsage extends InsideClassMultinameUsage {
|
||||
public class ExtendsMultinameUsage extends MultinameUsage implements InsideClassMultinameUsageInterface {
|
||||
|
||||
private int classIndex;
|
||||
|
||||
public ExtendsMultinameUsage(ABC abc, int multinameIndex, int classIndex) {
|
||||
super(abc, multinameIndex, classIndex);
|
||||
super(abc, multinameIndex);
|
||||
this.classIndex = classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClassIndex() {
|
||||
return classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " extends";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-2
@@ -22,14 +22,28 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ImplementsMultinameUsage extends InsideClassMultinameUsage {
|
||||
public class ImplementsMultinameUsage extends MultinameUsage implements InsideClassMultinameUsageInterface {
|
||||
|
||||
private int classIndex;
|
||||
|
||||
public ImplementsMultinameUsage(ABC abc, int multinameIndex, int classIndex) {
|
||||
super(abc, multinameIndex, classIndex);
|
||||
super(abc, multinameIndex);
|
||||
this.classIndex = classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClassIndex() {
|
||||
return classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " implements";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-15
@@ -22,21 +22,9 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class InsideClassMultinameUsage extends MultinameUsage {
|
||||
public interface InsideClassMultinameUsageInterface {
|
||||
|
||||
public int classIndex;
|
||||
public int getClassIndex();
|
||||
|
||||
public InsideClassMultinameUsage(ABC abc, int multinameIndex, int classIndex) {
|
||||
super(abc, multinameIndex);
|
||||
this.classIndex = classIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "class " + abc.constants.getMultiname(abc.instance_info.get(classIndex).name_index).getNameWithNamespace(abc.constants).toPrintableString(true);
|
||||
}
|
||||
|
||||
public int getClassIndex() {
|
||||
return classIndex;
|
||||
}
|
||||
public ABC getAbc();
|
||||
}
|
||||
+6
@@ -33,4 +33,10 @@ public class MethodBodyMultinameUsage extends MethodMultinameUsage {
|
||||
public String toString() {
|
||||
return super.toString() + " body";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public abstract class MethodMultinameUsage extends TraitMultinameUsage {
|
||||
}
|
||||
((TraitMethodGetterSetter) traits.traits.get(traitIndex)).toStringHeader(null, convertData, "", abc, traitsType == TRAITS_TYPE_CLASS, ScriptExportMode.AS, -1/*FIXME*/, classIndex, writer, new ArrayList<>(), false);
|
||||
}
|
||||
return writer.toString();
|
||||
return writer.toString().trim();
|
||||
}
|
||||
|
||||
public int getTraitIndex() {
|
||||
|
||||
+13
@@ -33,4 +33,17 @@ public class MethodNameMultinameUsage extends MethodMultinameUsage implements De
|
||||
public String toString() {
|
||||
return super.toString() + " name";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
if ((other instanceof MethodNameMultinameUsage) || (other instanceof ConstVarNameMultinameUsage)) {
|
||||
TraitMultinameUsage otherTrait = (TraitMultinameUsage) other;
|
||||
if (otherTrait.classIndex == classIndex && otherTrait.traitsType == traitsType) {
|
||||
if (other.sameMultinameName(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
package com.jpexs.decompiler.flash.abc.usages;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -40,4 +44,47 @@ public abstract class MultinameUsage {
|
||||
return abc;
|
||||
}
|
||||
|
||||
protected boolean sameMultinameName(MultinameUsage other) {
|
||||
Multiname thisM = abc.constants.getMultiname(multinameIndex);
|
||||
Multiname otherM = other.abc.constants.getMultiname(other.multinameIndex);
|
||||
if (thisM == null && otherM == null) {
|
||||
return false;
|
||||
}
|
||||
if (thisM == null || otherM == null) {
|
||||
return false;
|
||||
}
|
||||
if ((thisM.kind == Multiname.QNAME || thisM.kind == Multiname.QNAMEA) && otherM.kind == thisM.kind) {
|
||||
String thisName = thisM.getName(abc.constants, new ArrayList<>(), true);
|
||||
String otherName = otherM.getName(other.abc.constants, new ArrayList<>(), true);
|
||||
Namespace thisNs = thisM.getNamespace(abc.constants);
|
||||
Namespace otherNs = otherM.getNamespace(other.abc.constants);
|
||||
if (!Objects.equals(thisName, otherName)) {
|
||||
System.err.println("not equal name: " + thisName + ", " + otherName);
|
||||
return false;
|
||||
}
|
||||
|
||||
//Both are custom namespaced
|
||||
if (thisNs.kind == Namespace.KIND_NAMESPACE && otherNs.kind == Namespace.KIND_NAMESPACE) {
|
||||
//compare those custom
|
||||
return Objects.equals(thisNs.getName(abc.constants), otherNs.getName(other.abc.constants));
|
||||
}
|
||||
//One is custom namespaced, other cannot be the same
|
||||
if (thisNs.kind == Namespace.KIND_NAMESPACE || otherNs.kind == Namespace.KIND_NAMESPACE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//public or package internal are colliding when have same package ns
|
||||
if ((thisNs.kind == Namespace.KIND_PACKAGE || thisNs.kind == Namespace.KIND_PACKAGE_INTERNAL)
|
||||
&& (otherNs.kind == Namespace.KIND_PACKAGE || otherNs.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
|
||||
return Objects.equals(thisNs.getName(abc.constants), otherNs.getName(other.abc.constants));
|
||||
}
|
||||
|
||||
//one of them is private/protected
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract boolean collides(MultinameUsage other);
|
||||
}
|
||||
|
||||
+12
-1
@@ -23,7 +23,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class TraitMultinameUsage extends MultinameUsage {
|
||||
public abstract class TraitMultinameUsage extends MultinameUsage implements InsideClassMultinameUsageInterface {
|
||||
|
||||
public int traitIndex;
|
||||
|
||||
@@ -53,4 +53,15 @@ public abstract class TraitMultinameUsage extends MultinameUsage {
|
||||
public String toString() {
|
||||
return "class " + abc.constants.getMultiname(abc.instance_info.get(classIndex).name_index).getNameWithNamespace(abc.constants).toPrintableString(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClassIndex() {
|
||||
return classIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,4 +36,9 @@ public class TypeNameMultinameUsage extends MultinameUsage {
|
||||
public String toString() {
|
||||
return "TypeName " + abc.constants.getMultiname(typename_index).toString(abc.constants, new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(MultinameUsage other) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user