From 294e97d7e4cda6cadb62918fd822e7d0d11f16a9 Mon Sep 17 00:00:00 2001 From: jeff Date: Sun, 15 Mar 2015 00:44:35 -0400 Subject: fix bugs in the mappings converter --- src/cuchaz/enigma/convert/MappingsConverter.java | 125 ++++++++++++++--------- 1 file changed, 76 insertions(+), 49 deletions(-) (limited to 'src/cuchaz/enigma/convert/MappingsConverter.java') diff --git a/src/cuchaz/enigma/convert/MappingsConverter.java b/src/cuchaz/enigma/convert/MappingsConverter.java index 59f3b5b..ddd3a53 100644 --- a/src/cuchaz/enigma/convert/MappingsConverter.java +++ b/src/cuchaz/enigma/convert/MappingsConverter.java @@ -183,7 +183,7 @@ public class MappingsConverter { return newMappings; } - private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping mapping, final ClassMatches matches, boolean useSimpleName) { + private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping oldClassMapping, final ClassMatches matches, boolean useSimpleName) { ClassNameReplacer replacer = new ClassNameReplacer() { @Override @@ -196,30 +196,28 @@ public class MappingsConverter { } }; - ClassMapping newMapping; - String deobfName = mapping.getDeobfName(); + ClassMapping newClassMapping; + String deobfName = oldClassMapping.getDeobfName(); if (deobfName != null) { if (useSimpleName) { deobfName = new ClassEntry(deobfName).getSimpleName(); } - newMapping = new ClassMapping(newObfClass.getName(), deobfName); + newClassMapping = new ClassMapping(newObfClass.getName(), deobfName); } else { - newMapping = new ClassMapping(newObfClass.getName()); + newClassMapping = new ClassMapping(newObfClass.getName()); } // copy fields - for (FieldMapping fieldMapping : mapping.fields()) { - // TODO: map field obf names too... - newMapping.addFieldMapping(new FieldMapping(fieldMapping, replacer)); + for (FieldMapping fieldMapping : oldClassMapping.fields()) { + newClassMapping.addFieldMapping(new FieldMapping(fieldMapping, replacer)); } // copy methods - for (MethodMapping methodMapping : mapping.methods()) { - // TODO: map method obf names too... - newMapping.addMethodMapping(new MethodMapping(methodMapping, replacer)); + for (MethodMapping methodMapping : oldClassMapping.methods()) { + newClassMapping.addMethodMapping(new MethodMapping(methodMapping, replacer)); } - return newMapping; + return newClassMapping; } public static void convertMappings(Mappings mappings, BiMap changes) { @@ -262,8 +260,9 @@ public class MappingsConverter { Collection getObfEntries(JarIndex jarIndex); Collection> getMappings(ClassMapping destClassMapping); Set filterEntries(Collection obfEntries, T obfSourceEntry, ClassMatches classMatches); - void setMemberObfName(ClassMapping classMapping, MemberMapping memberMapping, String newObfName); + void setUpdateObfMember(ClassMapping classMapping, MemberMapping memberMapping, T newEntry); boolean hasObfMember(ClassMapping classMapping, T obfEntry); + void removeMemberByObf(ClassMapping classMapping, T obfEntry); } public static Doer getFieldDoer() { @@ -297,15 +296,20 @@ public class MappingsConverter { } @Override - public void setMemberObfName(ClassMapping classMapping, MemberMapping memberMapping, String newObfName) { + public void setUpdateObfMember(ClassMapping classMapping, MemberMapping memberMapping, FieldEntry newField) { FieldMapping fieldMapping = (FieldMapping)memberMapping; - classMapping.setFieldObfName(fieldMapping.getObfName(), fieldMapping.getObfType(), newObfName); + classMapping.setFieldObfNameAndType(fieldMapping.getObfName(), fieldMapping.getObfType(), newField.getName(), newField.getType()); } @Override public boolean hasObfMember(ClassMapping classMapping, FieldEntry obfField) { return classMapping.getFieldByObf(obfField.getName(), obfField.getType()) != null; } + + @Override + public void removeMemberByObf(ClassMapping classMapping, FieldEntry obfField) { + classMapping.removeFieldMapping(classMapping.getFieldByObf(obfField.getName(), obfField.getType())); + } }; } @@ -344,15 +348,20 @@ public class MappingsConverter { } @Override - public void setMemberObfName(ClassMapping classMapping, MemberMapping memberMapping, String newObfName) { + public void setUpdateObfMember(ClassMapping classMapping, MemberMapping memberMapping, BehaviorEntry newBehavior) { MethodMapping methodMapping = (MethodMapping)memberMapping; - classMapping.setMethodObfName(methodMapping.getObfName(), methodMapping.getObfSignature(), newObfName); + classMapping.setMethodObfNameAndSignature(methodMapping.getObfName(), methodMapping.getObfSignature(), newBehavior.getName(), newBehavior.getSignature()); } @Override public boolean hasObfMember(ClassMapping classMapping, BehaviorEntry obfBehavior) { return classMapping.getMethodByObf(obfBehavior.getName(), obfBehavior.getSignature()) != null; } + + @Override + public void removeMemberByObf(ClassMapping classMapping, BehaviorEntry obfBehavior) { + classMapping.removeMethodMapping(classMapping.getMethodByObf(obfBehavior.getName(), obfBehavior.getSignature())); + } }; } @@ -477,56 +486,74 @@ public class MappingsConverter { }); } - public static void applyMemberMatches(Mappings mappings, MemberMatches memberMatches, Doer doer) { + public static void applyMemberMatches(Mappings mappings, ClassMatches classMatches, MemberMatches memberMatches, Doer doer) { for (ClassMapping classMapping : mappings.classes()) { - applyMemberMatches(classMapping, memberMatches, doer); + applyMemberMatches(classMapping, classMatches, memberMatches, doer); } } - private static void applyMemberMatches(ClassMapping classMapping, MemberMatches memberMatches, Doer doer) { - ClassEntry classEntry = classMapping.getObfEntry(); + private static void applyMemberMatches(ClassMapping classMapping, ClassMatches classMatches, MemberMatches memberMatches, Doer doer) { + + // get the classes + ClassEntry obfDestClass = classMapping.getObfEntry(); // make a map of all the renames we need to make Map renames = Maps.newHashMap(); for (MemberMapping memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { - T obfSourceEntry = memberMapping.getObfEntry(classEntry); - T obfDestEntry = memberMatches.matches().get(obfSourceEntry); - if (obfDestEntry != null) { - if (obfDestEntry.getName().equals(obfSourceEntry.getName())) { - // same name, don't need to change anything - continue; - } - renames.put(obfSourceEntry, obfDestEntry); + T obfOldDestEntry = memberMapping.getObfEntry(obfDestClass); + T obfSourceEntry = getSourceEntryFromDestMapping(memberMapping, obfDestClass, classMatches); + + // but drop the unmatchable things + if (memberMatches.isUnmatchableSourceEntry(obfSourceEntry)) { + doer.removeMemberByObf(classMapping, obfOldDestEntry); + continue; + } + + T obfNewDestEntry = memberMatches.matches().get(obfSourceEntry); + if (obfNewDestEntry != null && !obfOldDestEntry.getName().equals(obfNewDestEntry.getName())) { + renames.put(obfOldDestEntry, obfNewDestEntry); } } - // apply to this class (should never need more than n passes) - int numRenames = renames.size(); - for (int i=0; i memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { - T obfSourceEntry = memberMapping.getObfEntry(classEntry); - T obfDestEntry = renames.get(obfSourceEntry); - if (obfDestEntry != null) { - // make sure this rename won't cause a collision - if (!doer.hasObfMember(classMapping, obfDestEntry)) { - doer.setMemberObfName(classMapping, memberMapping, obfDestEntry.getName()); - renames.remove(obfSourceEntry); + if (!renames.isEmpty()) { + + // apply to this class (should never need more than n passes) + int numRenamesAppliedThisRound; + do { + numRenamesAppliedThisRound = 0; + + for (MemberMapping memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { + T obfOldDestEntry = memberMapping.getObfEntry(obfDestClass); + T obfNewDestEntry = renames.get(obfOldDestEntry); + if (obfNewDestEntry != null) { + // make sure this rename won't cause a collision + // otherwise, save it for the next round and try again next time + if (!doer.hasObfMember(classMapping, obfNewDestEntry)) { + doer.setUpdateObfMember(classMapping, memberMapping, obfNewDestEntry); + renames.remove(obfOldDestEntry); + numRenamesAppliedThisRound++; + } } } - } - } - if (!renames.isEmpty()) { - System.err.println(String.format("WARNING: Couldn't apply all the renames for class %s. %d/%d renames left.", - classMapping.getObfFullName(), renames.size(), numRenames - )); - for (Map.Entry entry : renames.entrySet()) { - System.err.println(String.format("\t%s -> %s", entry.getKey(), entry.getValue())); + } while(numRenamesAppliedThisRound > 0); + + if (!renames.isEmpty()) { + System.err.println(String.format("WARNING: Couldn't apply all the renames for class %s. %d renames left.", + classMapping.getObfFullName(), renames.size() + )); + for (Map.Entry entry : renames.entrySet()) { + System.err.println(String.format("\t%s -> %s", entry.getKey().getName(), entry.getValue().getName())); + } } } // recurse for (ClassMapping innerClassMapping : classMapping.innerClasses()) { - applyMemberMatches(innerClassMapping, memberMatches, doer); + applyMemberMatches(innerClassMapping, classMatches, memberMatches, doer); } } + + private static T getSourceEntryFromDestMapping(MemberMapping destMemberMapping, ClassEntry obfDestClass, ClassMatches classMatches) { + return translate(destMemberMapping.getObfEntry(obfDestClass), classMatches.getUniqueMatches().inverse()); + } } -- cgit v1.2.3