diff --git a/jode/jode/obfuscator/ClassIdentifier.java b/jode/jode/obfuscator/ClassIdentifier.java index 090df65..f2a920c 100644 --- a/jode/jode/obfuscator/ClassIdentifier.java +++ b/jode/jode/obfuscator/ClassIdentifier.java @@ -66,8 +66,8 @@ public class ClassIdentifier extends Identifier { if (wildcard.matches(fullName + identifiers[i].getName()) || wildcard.matches(fullName + identifiers[i].getName() + "." +identifiers[i].getType())) { - if (GlobalOptions.verboseLevel > 1) - GlobalOptions.err.println("preserving "+identifiers[i]); + if (GlobalOptions.verboseLevel > 0) + GlobalOptions.err.println("Preserving "+identifiers[i]); setPreserved(); identifiers[i].setPreserved(); identifiers[i].setReachable(); @@ -94,18 +94,22 @@ public class ClassIdentifier extends Identifier { public void reachableIdentifier(String name, String typeSig, boolean isVirtual) { -// if (!isVirtual || (info.getModifiers() & Modifier.ABSTRACT) == 0) { - for (int i=0; i< identifiers.length; i++) { - if (name.equals(identifiers[i].getName()) - && typeSig.equals(identifiers[i].getType())) - identifiers[i].setReachable(); + boolean found = false; + for (int i=0; i< identifiers.length; i++) { + if (name.equals(identifiers[i].getName()) + && typeSig.equals(identifiers[i].getType())) { + identifiers[i].setReachable(); + found = true; } -// } + } + if (!found) { + /*XXXXXXXX super reachableIdentifier */ + } /*ELSE*/ if (isVirtual) { Enumeration enum = knownSubClasses.elements(); while (enum.hasMoreElements()) ((ClassIdentifier)enum.nextElement()) - .reachableIdentifier(name, typeSig, isVirtual); + .reachableIdentifier(name, typeSig, false); virtualReachables.addElement (new String[] { name, typeSig }); } @@ -136,10 +140,76 @@ public class ClassIdentifier extends Identifier { if ((ident.info.getModifiers() & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) identifiers[i].setPreserved(); + /* XXX - only preserve them if writeObject not existent + * or if writeObject calls defaultWriteObject + */ } } } + /** + * Marks the package as preserved, too. + */ + protected void setSinglePreserved() { + pack.setPreserved(); + } + + public void setSingleReachable() { + super.setSingleReachable(); + bundle.analyzeIdentifier(this); + } + + public void analyzeSuperClasses(ClassInfo superclass) { + while (superclass != null) { + if (superclass.getName().equals("java.lang.Serializable")) + preserveSerializable(); + + ClassIdentifier superident + = bundle.getClassIdentifier(superclass.getName()); + if (superident != null) { + superident.addSubClass(this); + } else { + // all virtual methods in superclass are reachable now! + MethodInfo[] topmethods = superclass.getMethods(); + for (int i=0; i< topmethods.length; i++) { + int modif = topmethods[i].getModifiers(); + if (((Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL) + & modif) == 0 + && !topmethods[i].getName().equals("")) { + reachableIdentifier + (topmethods[i].getName(), topmethods[i].getType(), + true); + } + } + } + ClassInfo[] ifaces = superclass.getInterfaces(); + for (int i=0; i < ifaces.length; i++) + initSuperClasses(ifaces[i]); + superclass = superclass.getSuperclass(); + } + } + + public void analyze() { + if (GlobalOptions.verboseLevel > 0) + GlobalOptions.err.println("Reachable: "+this); + + ClassInfo[] ifaces = info.getInterfaces(); + ifaceNames = new String[ifaces.length]; + for (int i=0; i < ifaces.length; i++) { + ifaceNames[i] = ifaces[i].getName(); + ClassIdentifier ifaceident + = bundle.getClassIdentifier(ifaceNames[i]); + analyzeSuperClasses(ifaces[i]); + } + + if (info.getSuperclass() != null) { + superName = info.getSuperclass().getName(); + ClassIdentifier superident + = bundle.getClassIdentifier(superName); + analyzeSuperClasses(info.getSuperclass()); + } + } + public void initSuperClasses(ClassInfo superclass) { while (superclass != null) { if (superclass.getName().equals("java.lang.Serializable")) @@ -172,9 +242,6 @@ public class ClassIdentifier extends Identifier { if (((Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL) & modif) == 0 && !topmethods[i].getName().equals("")) { - reachableIdentifier - (topmethods[i].getName(), topmethods[i].getType(), - true); preserveIdentifier (topmethods[i].getName(), topmethods[i].getType()); } @@ -187,16 +254,6 @@ public class ClassIdentifier extends Identifier { } } - public void setSingleReachable() { - super.setSingleReachable(); - bundle.analyzeIdentifier(this); - } - - public void analyze() { - if (GlobalOptions.verboseLevel > 0) - GlobalOptions.err.println("Reachable: "+this); - } - public void initClass() { info.loadInfo(info.FULLINFO); @@ -250,9 +307,6 @@ public class ClassIdentifier extends Identifier { ifaceNames[i] = ifaces[i].getName(); ClassIdentifier ifaceident = bundle.getClassIdentifier(ifaceNames[i]); - if (ifaceident != null) { - ifaceident.addSubClass(this); - } initSuperClasses(ifaces[i]); } @@ -260,11 +314,32 @@ public class ClassIdentifier extends Identifier { superName = info.getSuperclass().getName(); ClassIdentifier superident = bundle.getClassIdentifier(superName); - if (superident != null) { - superident.addSubClass(this); - } initSuperClasses(info.getSuperclass()); } + + // load inner classes + InnerClassInfo[] innerClasses = info.getInnerClasses(); + InnerClassInfo[] outerClasses = info.getOuterClasses(); + InnerClassInfo[] extraClasses = info.getExtraClasses(); + if (outerClasses != null) { + for (int i=0; i < outerClasses.length; i++) { + if (outerClasses[i].outer != null) { + bundle.getClassIdentifier(outerClasses[i].outer); + } + } + } + if (innerClasses != null) { + for (int i=0; i < innerClasses.length; i++) { + bundle.getClassIdentifier(innerClasses[i].inner); + } + } + if (extraClasses != null) { + for (int i=0; i < extraClasses.length; i++) { + bundle.getClassIdentifier(extraClasses[i].inner); + if (extraClasses[i].outer != null) + bundle.getClassIdentifier(extraClasses[i].outer); + } + } } public void buildTable(int renameRule) { @@ -330,61 +405,147 @@ public class ClassIdentifier extends Identifier { public void transformInnerClasses() { InnerClassInfo[] innerClasses = info.getInnerClasses(); - if (innerClasses == null) + InnerClassInfo[] outerClasses = info.getOuterClasses(); + InnerClassInfo[] extraClasses = info.getExtraClasses(); + if (innerClasses == null && outerClasses == null + && extraClasses == null) return; - int newInnerCount; + int newInnerCount, newOuterCount, newExtraCount; if (Obfuscator.shouldStrip) { - newInnerCount = 0; - for (int i=0; i < innerClasses.length; i++) { - ClassIdentifier innerIdent - = bundle.getClassIdentifier(innerClasses[i].inner); - if (innerIdent == null || innerIdent.isReachable()) + newInnerCount = newOuterCount = newExtraCount = 0; + if (outerClasses != null) { + for (int i=0; i < outerClasses.length; i++) { + if (outerClasses[i].outer != null) { + ClassIdentifier outerIdent + = bundle.getClassIdentifier(outerClasses[i].outer); + if (outerIdent == null || outerIdent.isReachable()) + newOuterCount++; + } else + newOuterCount++; + } + } + if (innerClasses != null) { + for (int i=0; i < innerClasses.length; i++) { + ClassIdentifier innerIdent + = bundle.getClassIdentifier(innerClasses[i].inner); + if (innerIdent == null || innerIdent.isReachable()) newInnerCount++; + } } - } else - newInnerCount = innerClasses.length; - - InnerClassInfo[] newInners = new InnerClassInfo[newInnerCount]; - newInnerCount = 0; + if (extraClasses != null) { + for (int i=0; i < extraClasses.length; i++) { + ClassIdentifier outerIdent = extraClasses[i].outer != null + ? bundle.getClassIdentifier(extraClasses[i].outer) + : null; + ClassIdentifier innerIdent + = bundle.getClassIdentifier(extraClasses[i].inner); + if ((outerIdent == null || outerIdent.isReachable()) + && (innerIdent == null || innerIdent.isReachable())) + newExtraCount++; + } + } + } else { + newInnerCount = innerClasses != null ? innerClasses.length : 0; + newOuterCount = outerClasses != null ? outerClasses.length : 0; + newExtraCount = extraClasses != null ? extraClasses.length : 0; + } - for (int i=0; i 0 + ? new InnerClassInfo[newInnerCount] : null; + InnerClassInfo[] newOuters = newOuterCount > 0 + ? new InnerClassInfo[newOuterCount] : null; + InnerClassInfo[] newExtras = newExtraCount > 0 + ? new InnerClassInfo[newExtraCount] : null; - String inner, outer, name; - if (innerIdent == null) { - inner = innerClasses[i].inner; - } else { - inner = innerIdent.getAlias(); - } - if (innerClasses[i].outer == null) { - outer = null; - } else { - ClassIdentifier outerIdent - = bundle.getClassIdentifier(innerClasses[i].outer); - if (outerIdent != null) { - if (Obfuscator.shouldStrip && !outerIdent.isReachable()) - outer = null; - else - outer = outerIdent.getAlias(); + if (newInners != null) { + int pos = 0; + for (int i=0; i