diff options
| author | 2015-02-02 21:26:10 -0500 | |
|---|---|---|
| committer | 2015-02-02 21:26:10 -0500 | |
| commit | 448685653e90415ebe10b08e8335462b81c30421 (patch) | |
| tree | 474d9bcc08c2b5441b704595992d3beff1d2587f | |
| parent | avoid concurrent modification exception (diff) | |
| download | enigma-448685653e90415ebe10b08e8335462b81c30421.tar.gz enigma-448685653e90415ebe10b08e8335462b81c30421.tar.xz enigma-448685653e90415ebe10b08e8335462b81c30421.zip | |
fix issue with bridge methods
18 files changed, 79 insertions, 113 deletions
| @@ -4,6 +4,7 @@ | |||
| 4 | <classpathentry kind="src" path="conf"/> | 4 | <classpathentry kind="src" path="conf"/> |
| 5 | <classpathentry kind="src" path="test"/> | 5 | <classpathentry kind="src" path="test"/> |
| 6 | <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | 6 | <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
| 7 | <classpathentry combineaccessrules="false" kind="src" path="/procyon"/> | ||
| 7 | <classpathentry kind="lib" path="lib/deps.jar"/> | 8 | <classpathentry kind="lib" path="lib/deps.jar"/> |
| 8 | <classpathentry kind="lib" path="lib/test-deps.jar"/> | 9 | <classpathentry kind="lib" path="lib/test-deps.jar"/> |
| 9 | <classpathentry kind="output" path="bin"/> | 10 | <classpathentry kind="output" path="bin"/> |
| @@ -28,7 +28,7 @@ ExtraRepos = [ | |||
| 28 | LibDeps = [ | 28 | LibDeps = [ |
| 29 | ssjb.ivy.Dep("com.google.guava:guava:17.0"), | 29 | ssjb.ivy.Dep("com.google.guava:guava:17.0"), |
| 30 | ssjb.ivy.Dep("org.javassist:javassist:3.18.1-GA"), | 30 | ssjb.ivy.Dep("org.javassist:javassist:3.18.1-GA"), |
| 31 | ssjb.ivy.Dep("org.bitbucket.mstrobel:procyon-decompiler:0.5.26-enigma") | 31 | ssjb.ivy.Dep("org.bitbucket.mstrobel:procyon-decompiler:0.5.28-enigma") |
| 32 | ] | 32 | ] |
| 33 | StandaloneDeps = LibDeps + [ | 33 | StandaloneDeps = LibDeps + [ |
| 34 | ssjb.ivy.Dep("de.sciss:jsyntaxpane:1.0.0") | 34 | ssjb.ivy.Dep("de.sciss:jsyntaxpane:1.0.0") |
| @@ -47,7 +47,7 @@ def buildTestJar(name, glob): | |||
| 47 | pathObfJar = os.path.join(DirBuild, "%s.obf.jar" % name) | 47 | pathObfJar = os.path.join(DirBuild, "%s.obf.jar" % name) |
| 48 | 48 | ||
| 49 | # build the deobf jar | 49 | # build the deobf jar |
| 50 | with ssjb.file.TempDir(DirTemp) as dirTemp: | 50 | with ssjb.file.TempDir("tmp") as dirTemp: |
| 51 | ssjb.file.copyTree(dirTemp, DirBin, ssjb.file.find(DirBin, "cuchaz/enigma/inputs/Keep.class")) | 51 | ssjb.file.copyTree(dirTemp, DirBin, ssjb.file.find(DirBin, "cuchaz/enigma/inputs/Keep.class")) |
| 52 | ssjb.file.copyTree(dirTemp, DirBin, ssjb.file.find(DirBin, glob)) | 52 | ssjb.file.copyTree(dirTemp, DirBin, ssjb.file.find(DirBin, glob)) |
| 53 | ssjb.jar.makeJar(pathJar, dirTemp) | 53 | ssjb.jar.makeJar(pathJar, dirTemp) |
| @@ -96,7 +96,7 @@ def buildLibJar(dirOut): | |||
| 96 | 96 | ||
| 97 | def taskGetDeps(): | 97 | def taskGetDeps(): |
| 98 | ssjb.file.mkdir(DirLib) | 98 | ssjb.file.mkdir(DirLib) |
| 99 | ssjb.ivy.makeLibsJar(os.path.join(DirLib, "deps.jar"), Deps, extraRepos=ExtraRepos) | 99 | ssjb.ivy.makeLibsJar(os.path.join(DirLib, "deps.jar"), StandaloneDeps, extraRepos=ExtraRepos) |
| 100 | ssjb.ivy.makeLibsJar(os.path.join(DirLib, "test-deps.jar"), TestDeps) | 100 | ssjb.ivy.makeLibsJar(os.path.join(DirLib, "test-deps.jar"), TestDeps) |
| 101 | ssjb.ivy.makeJar(os.path.join(DirLib, "proguard.jar"), ProguardDep) | 101 | ssjb.ivy.makeJar(os.path.join(DirLib, "proguard.jar"), ProguardDep) |
| 102 | 102 | ||
diff --git a/src/cuchaz/enigma/CommandMain.java b/src/cuchaz/enigma/CommandMain.java index 74bd4991..1ec2ad23 100644 --- a/src/cuchaz/enigma/CommandMain.java +++ b/src/cuchaz/enigma/CommandMain.java | |||
| @@ -2,6 +2,7 @@ package cuchaz.enigma; | |||
| 2 | 2 | ||
| 3 | import java.io.File; | 3 | import java.io.File; |
| 4 | import java.io.FileReader; | 4 | import java.io.FileReader; |
| 5 | import java.util.jar.JarFile; | ||
| 5 | 6 | ||
| 6 | import cuchaz.enigma.Deobfuscator.ProgressListener; | 7 | import cuchaz.enigma.Deobfuscator.ProgressListener; |
| 7 | import cuchaz.enigma.mapping.Mappings; | 8 | import cuchaz.enigma.mapping.Mappings; |
| @@ -78,7 +79,7 @@ public class CommandMain { | |||
| 78 | File fileMappings = getReadableFile(getArg(args, 1, "mappings file")); | 79 | File fileMappings = getReadableFile(getArg(args, 1, "mappings file")); |
| 79 | File fileJarIn = getReadableFile(getArg(args, 2, "in jar")); | 80 | File fileJarIn = getReadableFile(getArg(args, 2, "in jar")); |
| 80 | File fileJarOut = getWritableFolder(getArg(args, 3, "out folder")); | 81 | File fileJarOut = getWritableFolder(getArg(args, 3, "out folder")); |
| 81 | Deobfuscator deobfuscator = getDeobfuscator(fileMappings, fileJarIn); | 82 | Deobfuscator deobfuscator = getDeobfuscator(fileMappings, new JarFile(fileJarIn)); |
| 82 | deobfuscator.writeSources(fileJarOut, new ConsoleProgressListener()); | 83 | deobfuscator.writeSources(fileJarOut, new ConsoleProgressListener()); |
| 83 | } | 84 | } |
| 84 | 85 | ||
| @@ -87,16 +88,16 @@ public class CommandMain { | |||
| 87 | File fileMappings = getReadableFile(getArg(args, 1, "mappings file")); | 88 | File fileMappings = getReadableFile(getArg(args, 1, "mappings file")); |
| 88 | File fileJarIn = getReadableFile(getArg(args, 2, "in jar")); | 89 | File fileJarIn = getReadableFile(getArg(args, 2, "in jar")); |
| 89 | File fileJarOut = getWritableFile(getArg(args, 3, "out jar")); | 90 | File fileJarOut = getWritableFile(getArg(args, 3, "out jar")); |
| 90 | Deobfuscator deobfuscator = getDeobfuscator(fileMappings, fileJarIn); | 91 | Deobfuscator deobfuscator = getDeobfuscator(fileMappings, new JarFile(fileJarIn)); |
| 91 | deobfuscator.writeJar(fileJarOut, new ConsoleProgressListener()); | 92 | deobfuscator.writeJar(fileJarOut, new ConsoleProgressListener()); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | private static Deobfuscator getDeobfuscator(File fileMappings, File fileJar) | 95 | private static Deobfuscator getDeobfuscator(File fileMappings, JarFile jar) |
| 95 | throws Exception { | 96 | throws Exception { |
| 96 | System.out.println("Reading mappings..."); | 97 | System.out.println("Reading mappings..."); |
| 97 | Mappings mappings = new MappingsReader().read(new FileReader(fileMappings)); | 98 | Mappings mappings = new MappingsReader().read(new FileReader(fileMappings)); |
| 98 | System.out.println("Reading jar..."); | 99 | System.out.println("Reading jar..."); |
| 99 | Deobfuscator deobfuscator = new Deobfuscator(fileJar); | 100 | Deobfuscator deobfuscator = new Deobfuscator(jar); |
| 100 | deobfuscator.setMappings(mappings); | 101 | deobfuscator.setMappings(mappings); |
| 101 | return deobfuscator; | 102 | return deobfuscator; |
| 102 | } | 103 | } |
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index 22c517a1..62c062a5 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java | |||
| @@ -68,7 +68,6 @@ public class Deobfuscator { | |||
| 68 | void onProgress(int numDone, String message); | 68 | void onProgress(int numDone, String message); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | private File m_file; | ||
| 72 | private JarFile m_jar; | 71 | private JarFile m_jar; |
| 73 | private DecompilerSettings m_settings; | 72 | private DecompilerSettings m_settings; |
| 74 | private JarIndex m_jarIndex; | 73 | private JarIndex m_jarIndex; |
| @@ -76,9 +75,8 @@ public class Deobfuscator { | |||
| 76 | private MappingsRenamer m_renamer; | 75 | private MappingsRenamer m_renamer; |
| 77 | private Map<TranslationDirection,Translator> m_translatorCache; | 76 | private Map<TranslationDirection,Translator> m_translatorCache; |
| 78 | 77 | ||
| 79 | public Deobfuscator(File file) throws IOException { | 78 | public Deobfuscator(JarFile jar) throws IOException { |
| 80 | m_file = file; | 79 | m_jar = jar; |
| 81 | m_jar = new JarFile(m_file); | ||
| 82 | 80 | ||
| 83 | // build the jar index | 81 | // build the jar index |
| 84 | m_jarIndex = new JarIndex(); | 82 | m_jarIndex = new JarIndex(); |
| @@ -100,7 +98,7 @@ public class Deobfuscator { | |||
| 100 | } | 98 | } |
| 101 | 99 | ||
| 102 | public String getJarName() { | 100 | public String getJarName() { |
| 103 | return m_file.getName(); | 101 | return m_jar.getName(); |
| 104 | } | 102 | } |
| 105 | 103 | ||
| 106 | public JarIndex getJarIndex() { | 104 | public JarIndex getJarIndex() { |
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java index 091f916d..9287999b 100644 --- a/src/cuchaz/enigma/TranslatingTypeLoader.java +++ b/src/cuchaz/enigma/TranslatingTypeLoader.java | |||
| @@ -29,7 +29,6 @@ import com.strobel.assembler.metadata.Buffer; | |||
| 29 | import com.strobel.assembler.metadata.ClasspathTypeLoader; | 29 | import com.strobel.assembler.metadata.ClasspathTypeLoader; |
| 30 | import com.strobel.assembler.metadata.ITypeLoader; | 30 | import com.strobel.assembler.metadata.ITypeLoader; |
| 31 | 31 | ||
| 32 | import cuchaz.enigma.analysis.BridgeFixer; | ||
| 33 | import cuchaz.enigma.analysis.JarIndex; | 32 | import cuchaz.enigma.analysis.JarIndex; |
| 34 | import cuchaz.enigma.bytecode.ClassRenamer; | 33 | import cuchaz.enigma.bytecode.ClassRenamer; |
| 35 | import cuchaz.enigma.bytecode.ClassTranslator; | 34 | import cuchaz.enigma.bytecode.ClassTranslator; |
| @@ -168,7 +167,7 @@ public class TranslatingTypeLoader implements ITypeLoader { | |||
| 168 | assertClassName(c, deobfClassEntry); | 167 | assertClassName(c, deobfClassEntry); |
| 169 | 168 | ||
| 170 | // DEBUG | 169 | // DEBUG |
| 171 | // Util.writeClass( c ); | 170 | Util.writeClass( c ); |
| 172 | 171 | ||
| 173 | // we have a transformed class! | 172 | // we have a transformed class! |
| 174 | return c.toBytecode(); | 173 | return c.toBytecode(); |
| @@ -196,7 +195,6 @@ public class TranslatingTypeLoader implements ITypeLoader { | |||
| 196 | assertClassName(c, obfClassEntry); | 195 | assertClassName(c, obfClassEntry); |
| 197 | 196 | ||
| 198 | // do all kinds of deobfuscating transformations on the class | 197 | // do all kinds of deobfuscating transformations on the class |
| 199 | new BridgeFixer(m_jarIndex).fixBridges(c); | ||
| 200 | new MethodParameterWriter(m_deobfuscatingTranslator).writeMethodArguments(c); | 198 | new MethodParameterWriter(m_deobfuscatingTranslator).writeMethodArguments(c); |
| 201 | new ClassTranslator(m_deobfuscatingTranslator).translate(c); | 199 | new ClassTranslator(m_deobfuscatingTranslator).translate(c); |
| 202 | 200 | ||
diff --git a/src/cuchaz/enigma/analysis/BridgeFixer.java b/src/cuchaz/enigma/analysis/BridgeFixer.java deleted file mode 100644 index ad23b000..00000000 --- a/src/cuchaz/enigma/analysis/BridgeFixer.java +++ /dev/null | |||
| @@ -1,72 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2014 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Public License v3.0 | ||
| 5 | * which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/gpl.html | ||
| 7 | * | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.analysis; | ||
| 12 | |||
| 13 | import javassist.CtClass; | ||
| 14 | import javassist.CtMethod; | ||
| 15 | import javassist.bytecode.ConstPool; | ||
| 16 | import javassist.bytecode.Descriptor; | ||
| 17 | import cuchaz.enigma.bytecode.ConstPoolEditor; | ||
| 18 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 19 | import cuchaz.enigma.mapping.BehaviorEntryFactory; | ||
| 20 | import cuchaz.enigma.mapping.ClassEntry; | ||
| 21 | import cuchaz.enigma.mapping.MethodEntry; | ||
| 22 | |||
| 23 | public class BridgeFixer { | ||
| 24 | |||
| 25 | private JarIndex m_index; | ||
| 26 | |||
| 27 | public BridgeFixer(JarIndex index) { | ||
| 28 | m_index = index; | ||
| 29 | } | ||
| 30 | |||
| 31 | public void fixBridges(CtClass c) { | ||
| 32 | // rename declared methods | ||
| 33 | for (CtMethod method : c.getDeclaredMethods()) { | ||
| 34 | // get the method entry | ||
| 35 | MethodEntry methodEntry = new MethodEntry( | ||
| 36 | new ClassEntry(Descriptor.toJvmName(c.getName())), | ||
| 37 | method.getName(), | ||
| 38 | method.getSignature() | ||
| 39 | ); | ||
| 40 | MethodEntry bridgeMethodEntry = m_index.getBridgeMethod(methodEntry); | ||
| 41 | if (bridgeMethodEntry != null) { | ||
| 42 | // fix this bridged method | ||
| 43 | method.setName(bridgeMethodEntry.getName()); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | // rename method references | ||
| 48 | // translate all the field and method references in the code by editing the constant pool | ||
| 49 | ConstPool constants = c.getClassFile().getConstPool(); | ||
| 50 | ConstPoolEditor editor = new ConstPoolEditor(constants); | ||
| 51 | for (int i = 1; i < constants.getSize(); i++) { | ||
| 52 | switch (constants.getTag(i)) { | ||
| 53 | case ConstPool.CONST_Methodref: | ||
| 54 | case ConstPool.CONST_InterfaceMethodref: { | ||
| 55 | BehaviorEntry behaviorEntry = BehaviorEntryFactory.create(Descriptor.toJvmName(editor.getMemberrefClassname(i)), editor.getMemberrefName(i), editor.getMemberrefType(i)); | ||
| 56 | |||
| 57 | if (behaviorEntry instanceof MethodEntry) { | ||
| 58 | MethodEntry methodEntry = (MethodEntry)behaviorEntry; | ||
| 59 | |||
| 60 | // translate the name and type | ||
| 61 | MethodEntry bridgeMethodEntry = m_index.getBridgeMethod(methodEntry); | ||
| 62 | if (bridgeMethodEntry != null) { | ||
| 63 | // FIXIT FIXIT FIXIT FIXIT FIXIT FIXIT FIXIT | ||
| 64 | editor.changeMemberrefNameAndType(i, bridgeMethodEntry.getName(), bridgeMethodEntry.getSignature()); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index 86ba93b2..e652202c 100644 --- a/src/cuchaz/enigma/gui/Gui.java +++ b/src/cuchaz/enigma/gui/Gui.java | |||
| @@ -33,6 +33,7 @@ import java.util.Collection; | |||
| 33 | import java.util.Collections; | 33 | import java.util.Collections; |
| 34 | import java.util.List; | 34 | import java.util.List; |
| 35 | import java.util.Vector; | 35 | import java.util.Vector; |
| 36 | import java.util.jar.JarFile; | ||
| 36 | 37 | ||
| 37 | import javax.swing.BorderFactory; | 38 | import javax.swing.BorderFactory; |
| 38 | import javax.swing.JEditorPane; | 39 | import javax.swing.JEditorPane; |
| @@ -499,7 +500,7 @@ public class Gui { | |||
| 499 | @Override | 500 | @Override |
| 500 | public void run() { | 501 | public void run() { |
| 501 | try { | 502 | try { |
| 502 | m_controller.openJar(m_jarFileChooser.getSelectedFile()); | 503 | m_controller.openJar(new JarFile(m_jarFileChooser.getSelectedFile())); |
| 503 | } catch (IOException ex) { | 504 | } catch (IOException ex) { |
| 504 | throw new Error(ex); | 505 | throw new Error(ex); |
| 505 | } | 506 | } |
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index 908c16fa..61fea9c0 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java | |||
| @@ -17,6 +17,7 @@ import java.io.IOException; | |||
| 17 | import java.util.Collection; | 17 | import java.util.Collection; |
| 18 | import java.util.Deque; | 18 | import java.util.Deque; |
| 19 | import java.util.List; | 19 | import java.util.List; |
| 20 | import java.util.jar.JarFile; | ||
| 20 | 21 | ||
| 21 | import com.google.common.collect.Lists; | 22 | import com.google.common.collect.Lists; |
| 22 | import com.google.common.collect.Queues; | 23 | import com.google.common.collect.Queues; |
| @@ -66,9 +67,9 @@ public class GuiController { | |||
| 66 | return m_isDirty; | 67 | return m_isDirty; |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | public void openJar(final File file) throws IOException { | 70 | public void openJar(final JarFile jar) throws IOException { |
| 70 | m_gui.onStartOpenJar(); | 71 | m_gui.onStartOpenJar(); |
| 71 | m_deobfuscator = new Deobfuscator(file); | 72 | m_deobfuscator = new Deobfuscator(jar); |
| 72 | m_gui.onFinishOpenJar(m_deobfuscator.getJarName()); | 73 | m_gui.onFinishOpenJar(m_deobfuscator.getJarName()); |
| 73 | refreshClasses(); | 74 | refreshClasses(); |
| 74 | } | 75 | } |
diff --git a/test/cuchaz/enigma/TestDeobfuscator.java b/test/cuchaz/enigma/TestDeobfuscator.java index 6ac4c786..129d7b25 100644 --- a/test/cuchaz/enigma/TestDeobfuscator.java +++ b/test/cuchaz/enigma/TestDeobfuscator.java | |||
| @@ -13,9 +13,9 @@ package cuchaz.enigma; | |||
| 13 | 13 | ||
| 14 | import static org.junit.Assert.*; | 14 | import static org.junit.Assert.*; |
| 15 | 15 | ||
| 16 | import java.io.File; | ||
| 17 | import java.io.IOException; | 16 | import java.io.IOException; |
| 18 | import java.util.List; | 17 | import java.util.List; |
| 18 | import java.util.jar.JarFile; | ||
| 19 | 19 | ||
| 20 | import org.junit.Test; | 20 | import org.junit.Test; |
| 21 | 21 | ||
| @@ -26,7 +26,7 @@ import cuchaz.enigma.mapping.ClassEntry; | |||
| 26 | public class TestDeobfuscator { | 26 | public class TestDeobfuscator { |
| 27 | 27 | ||
| 28 | private Deobfuscator getDeobfuscator() throws IOException { | 28 | private Deobfuscator getDeobfuscator() throws IOException { |
| 29 | return new Deobfuscator(new File("build/testLoneClass.obf.jar")); | 29 | return new Deobfuscator(new JarFile("build/testLoneClass.obf.jar")); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | @Test | 32 | @Test |
diff --git a/test/cuchaz/enigma/TestInnerClasses.java b/test/cuchaz/enigma/TestInnerClasses.java index 51fb5e35..63c9b719 100644 --- a/test/cuchaz/enigma/TestInnerClasses.java +++ b/test/cuchaz/enigma/TestInnerClasses.java | |||
| @@ -23,6 +23,7 @@ import cuchaz.enigma.analysis.JarIndex; | |||
| 23 | public class TestInnerClasses { | 23 | public class TestInnerClasses { |
| 24 | 24 | ||
| 25 | private JarIndex m_index; | 25 | private JarIndex m_index; |
| 26 | private Deobfuscator m_deobfuscator; | ||
| 26 | 27 | ||
| 27 | private static final String AnonymousOuter = "none/a"; | 28 | private static final String AnonymousOuter = "none/a"; |
| 28 | private static final String AnonymousInner = "b"; | 29 | private static final String AnonymousInner = "b"; |
| @@ -32,10 +33,14 @@ public class TestInnerClasses { | |||
| 32 | private static final String ConstructorArgsInner = "f"; | 33 | private static final String ConstructorArgsInner = "f"; |
| 33 | private static final String AnonymousWithScopeArgsOuter = "none/c"; | 34 | private static final String AnonymousWithScopeArgsOuter = "none/c"; |
| 34 | private static final String AnonymousWithScopeArgsInner = "d"; | 35 | private static final String AnonymousWithScopeArgsInner = "d"; |
| 36 | private static final String AnonymousWithOuterAccessOuter = "none/i"; | ||
| 37 | private static final String AnonymousWithOuterAccessInner = "j"; | ||
| 35 | 38 | ||
| 36 | public TestInnerClasses() throws Exception { | 39 | public TestInnerClasses() throws Exception { |
| 37 | m_index = new JarIndex(); | 40 | m_index = new JarIndex(); |
| 38 | m_index.indexJar(new JarFile("build/testInnerClasses.obf.jar"), true); | 41 | JarFile jar = new JarFile("build/testInnerClasses.obf.jar"); |
| 42 | m_index.indexJar(jar, true); | ||
| 43 | m_deobfuscator = new Deobfuscator(jar); | ||
| 39 | } | 44 | } |
| 40 | 45 | ||
| 41 | @Test | 46 | @Test |
| @@ -43,6 +48,7 @@ public class TestInnerClasses { | |||
| 43 | assertThat(m_index.getOuterClass(SimpleInner), is(SimpleOuter)); | 48 | assertThat(m_index.getOuterClass(SimpleInner), is(SimpleOuter)); |
| 44 | assertThat(m_index.getInnerClasses(SimpleOuter), containsInAnyOrder(SimpleInner)); | 49 | assertThat(m_index.getInnerClasses(SimpleOuter), containsInAnyOrder(SimpleInner)); |
| 45 | assertThat(m_index.isAnonymousClass(SimpleInner), is(false)); | 50 | assertThat(m_index.isAnonymousClass(SimpleInner), is(false)); |
| 51 | decompile(SimpleOuter); | ||
| 46 | } | 52 | } |
| 47 | 53 | ||
| 48 | @Test | 54 | @Test |
| @@ -50,6 +56,7 @@ public class TestInnerClasses { | |||
| 50 | assertThat(m_index.getOuterClass(AnonymousInner), is(AnonymousOuter)); | 56 | assertThat(m_index.getOuterClass(AnonymousInner), is(AnonymousOuter)); |
| 51 | assertThat(m_index.getInnerClasses(AnonymousOuter), containsInAnyOrder(AnonymousInner)); | 57 | assertThat(m_index.getInnerClasses(AnonymousOuter), containsInAnyOrder(AnonymousInner)); |
| 52 | assertThat(m_index.isAnonymousClass(AnonymousInner), is(true)); | 58 | assertThat(m_index.isAnonymousClass(AnonymousInner), is(true)); |
| 59 | decompile(AnonymousOuter); | ||
| 53 | } | 60 | } |
| 54 | 61 | ||
| 55 | @Test | 62 | @Test |
| @@ -57,6 +64,7 @@ public class TestInnerClasses { | |||
| 57 | assertThat(m_index.getOuterClass(ConstructorArgsInner), is(ConstructorArgsOuter)); | 64 | assertThat(m_index.getOuterClass(ConstructorArgsInner), is(ConstructorArgsOuter)); |
| 58 | assertThat(m_index.getInnerClasses(ConstructorArgsOuter), containsInAnyOrder(ConstructorArgsInner)); | 65 | assertThat(m_index.getInnerClasses(ConstructorArgsOuter), containsInAnyOrder(ConstructorArgsInner)); |
| 59 | assertThat(m_index.isAnonymousClass(ConstructorArgsInner), is(false)); | 66 | assertThat(m_index.isAnonymousClass(ConstructorArgsInner), is(false)); |
| 67 | decompile(ConstructorArgsOuter); | ||
| 60 | } | 68 | } |
| 61 | 69 | ||
| 62 | @Test | 70 | @Test |
| @@ -64,5 +72,18 @@ public class TestInnerClasses { | |||
| 64 | assertThat(m_index.getOuterClass(AnonymousWithScopeArgsInner), is(AnonymousWithScopeArgsOuter)); | 72 | assertThat(m_index.getOuterClass(AnonymousWithScopeArgsInner), is(AnonymousWithScopeArgsOuter)); |
| 65 | assertThat(m_index.getInnerClasses(AnonymousWithScopeArgsOuter), containsInAnyOrder(AnonymousWithScopeArgsInner)); | 73 | assertThat(m_index.getInnerClasses(AnonymousWithScopeArgsOuter), containsInAnyOrder(AnonymousWithScopeArgsInner)); |
| 66 | assertThat(m_index.isAnonymousClass(AnonymousWithScopeArgsInner), is(true)); | 74 | assertThat(m_index.isAnonymousClass(AnonymousWithScopeArgsInner), is(true)); |
| 75 | decompile(AnonymousWithScopeArgsOuter); | ||
| 76 | } | ||
| 77 | |||
| 78 | @Test | ||
| 79 | public void anonymousWithOuterAccess() { | ||
| 80 | assertThat(m_index.getOuterClass(AnonymousWithOuterAccessInner), is(AnonymousWithOuterAccessOuter)); | ||
| 81 | assertThat(m_index.getInnerClasses(AnonymousWithOuterAccessOuter), containsInAnyOrder(AnonymousWithOuterAccessInner)); | ||
| 82 | assertThat(m_index.isAnonymousClass(AnonymousWithOuterAccessInner), is(true)); | ||
| 83 | decompile(AnonymousWithOuterAccessOuter); | ||
| 84 | } | ||
| 85 | |||
| 86 | private void decompile(String name) { | ||
| 87 | m_deobfuscator.getSourceTree(name); | ||
| 67 | } | 88 | } |
| 68 | } | 89 | } |
diff --git a/test/cuchaz/enigma/TestSourceIndex.java b/test/cuchaz/enigma/TestSourceIndex.java index ba7fc797..70a5ee4c 100644 --- a/test/cuchaz/enigma/TestSourceIndex.java +++ b/test/cuchaz/enigma/TestSourceIndex.java | |||
| @@ -11,8 +11,8 @@ | |||
| 11 | ******************************************************************************/ | 11 | ******************************************************************************/ |
| 12 | package cuchaz.enigma; | 12 | package cuchaz.enigma; |
| 13 | 13 | ||
| 14 | import java.io.File; | ||
| 15 | import java.util.Set; | 14 | import java.util.Set; |
| 15 | import java.util.jar.JarFile; | ||
| 16 | 16 | ||
| 17 | import org.junit.Test; | 17 | import org.junit.Test; |
| 18 | 18 | ||
| @@ -26,7 +26,7 @@ public class TestSourceIndex { | |||
| 26 | // TEMP | 26 | // TEMP |
| 27 | @Test | 27 | @Test |
| 28 | public void indexEverything() throws Exception { | 28 | public void indexEverything() throws Exception { |
| 29 | Deobfuscator deobfuscator = new Deobfuscator(new File("input/1.8.jar")); | 29 | Deobfuscator deobfuscator = new Deobfuscator(new JarFile("input/1.8.jar")); |
| 30 | 30 | ||
| 31 | // get all classes that aren't inner classes | 31 | // get all classes that aren't inner classes |
| 32 | Set<ClassEntry> classEntries = Sets.newHashSet(); | 32 | Set<ClassEntry> classEntries = Sets.newHashSet(); |
diff --git a/test/cuchaz/enigma/TestTokensConstructors.java b/test/cuchaz/enigma/TestTokensConstructors.java index 9f85e81d..56424ae8 100644 --- a/test/cuchaz/enigma/TestTokensConstructors.java +++ b/test/cuchaz/enigma/TestTokensConstructors.java | |||
| @@ -10,15 +10,11 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma; | 11 | package cuchaz.enigma; |
| 12 | 12 | ||
| 13 | import static cuchaz.enigma.EntryFactory.newBehaviorReferenceByConstructor; | 13 | import static cuchaz.enigma.EntryFactory.*; |
| 14 | import static cuchaz.enigma.EntryFactory.newBehaviorReferenceByMethod; | 14 | import static org.hamcrest.MatcherAssert.*; |
| 15 | import static cuchaz.enigma.EntryFactory.newConstructor; | 15 | import static org.hamcrest.Matchers.*; |
| 16 | import static org.hamcrest.MatcherAssert.assertThat; | ||
| 17 | import static org.hamcrest.Matchers.containsInAnyOrder; | ||
| 18 | import static org.hamcrest.Matchers.is; | ||
| 19 | import static org.hamcrest.Matchers.nullValue; | ||
| 20 | 16 | ||
| 21 | import java.io.File; | 17 | import java.util.jar.JarFile; |
| 22 | 18 | ||
| 23 | import org.junit.Test; | 19 | import org.junit.Test; |
| 24 | 20 | ||
| @@ -27,7 +23,7 @@ import cuchaz.enigma.mapping.BehaviorEntry; | |||
| 27 | public class TestTokensConstructors extends TokenChecker { | 23 | public class TestTokensConstructors extends TokenChecker { |
| 28 | 24 | ||
| 29 | public TestTokensConstructors() throws Exception { | 25 | public TestTokensConstructors() throws Exception { |
| 30 | super(new File("build/testConstructors.obf.jar")); | 26 | super(new JarFile("build/testConstructors.obf.jar")); |
| 31 | } | 27 | } |
| 32 | 28 | ||
| 33 | @Test | 29 | @Test |
| @@ -63,11 +59,11 @@ public class TestTokensConstructors extends TokenChecker { | |||
| 63 | ); | 59 | ); |
| 64 | assertThat( | 60 | assertThat( |
| 65 | getReferenceTokens(newBehaviorReferenceByConstructor(source, "none/d", "()V")), | 61 | getReferenceTokens(newBehaviorReferenceByConstructor(source, "none/d", "()V")), |
| 66 | containsInAnyOrder("super") // implicit call, decompiled to "super" | 62 | is(empty()) // implicit call, not decompiled to token |
| 67 | ); | 63 | ); |
| 68 | assertThat( | 64 | assertThat( |
| 69 | getReferenceTokens(newBehaviorReferenceByConstructor(source, "none/d", "(III)V")), | 65 | getReferenceTokens(newBehaviorReferenceByConstructor(source, "none/d", "(III)V")), |
| 70 | containsInAnyOrder("super") // implicit call, decompiled to "super" | 66 | is(empty()) // implicit call, not decompiled to token |
| 71 | ); | 67 | ); |
| 72 | } | 68 | } |
| 73 | 69 | ||
diff --git a/test/cuchaz/enigma/TokenChecker.java b/test/cuchaz/enigma/TokenChecker.java index 524c5ec5..febea2ae 100644 --- a/test/cuchaz/enigma/TokenChecker.java +++ b/test/cuchaz/enigma/TokenChecker.java | |||
| @@ -10,10 +10,10 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma; | 11 | package cuchaz.enigma; |
| 12 | 12 | ||
| 13 | import java.io.File; | ||
| 14 | import java.io.IOException; | 13 | import java.io.IOException; |
| 15 | import java.util.Collection; | 14 | import java.util.Collection; |
| 16 | import java.util.List; | 15 | import java.util.List; |
| 16 | import java.util.jar.JarFile; | ||
| 17 | 17 | ||
| 18 | import com.google.common.collect.Lists; | 18 | import com.google.common.collect.Lists; |
| 19 | import com.strobel.decompiler.languages.java.ast.CompilationUnit; | 19 | import com.strobel.decompiler.languages.java.ast.CompilationUnit; |
| @@ -27,7 +27,7 @@ public class TokenChecker { | |||
| 27 | 27 | ||
| 28 | private Deobfuscator m_deobfuscator; | 28 | private Deobfuscator m_deobfuscator; |
| 29 | 29 | ||
| 30 | protected TokenChecker(File jarFile) throws IOException { | 30 | protected TokenChecker(JarFile jarFile) throws IOException { |
| 31 | m_deobfuscator = new Deobfuscator(jarFile); | 31 | m_deobfuscator = new Deobfuscator(jarFile); |
| 32 | } | 32 | } |
| 33 | 33 | ||
diff --git a/test/cuchaz/enigma/inputs/innerClasses/Anonymous.java b/test/cuchaz/enigma/inputs/innerClasses/A_Anonymous.java index f5d9d1cf..f7118f63 100644 --- a/test/cuchaz/enigma/inputs/innerClasses/Anonymous.java +++ b/test/cuchaz/enigma/inputs/innerClasses/A_Anonymous.java | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | package cuchaz.enigma.inputs.innerClasses; | 1 | package cuchaz.enigma.inputs.innerClasses; |
| 2 | 2 | ||
| 3 | public class Anonymous { | 3 | public class A_Anonymous { |
| 4 | 4 | ||
| 5 | public void foo() { | 5 | public void foo() { |
| 6 | Runnable runnable = new Runnable() { | 6 | Runnable runnable = new Runnable() { |
diff --git a/test/cuchaz/enigma/inputs/innerClasses/AnonymousWithScopeArgs.java b/test/cuchaz/enigma/inputs/innerClasses/B_AnonymousWithScopeArgs.java index b3ba1af8..42fba9a8 100644 --- a/test/cuchaz/enigma/inputs/innerClasses/AnonymousWithScopeArgs.java +++ b/test/cuchaz/enigma/inputs/innerClasses/B_AnonymousWithScopeArgs.java | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | package cuchaz.enigma.inputs.innerClasses; | 1 | package cuchaz.enigma.inputs.innerClasses; |
| 2 | 2 | ||
| 3 | public class AnonymousWithScopeArgs { | 3 | public class B_AnonymousWithScopeArgs { |
| 4 | 4 | ||
| 5 | public static void foo(final Simple arg) { | 5 | public static void foo(final D_Simple arg) { |
| 6 | System.out.println(new Object() { | 6 | System.out.println(new Object() { |
| 7 | @Override | 7 | @Override |
| 8 | public String toString() { | 8 | public String toString() { |
diff --git a/test/cuchaz/enigma/inputs/innerClasses/ConstructorArgs.java b/test/cuchaz/enigma/inputs/innerClasses/C_ConstructorArgs.java index 08135fe5..8fa6c5b8 100644 --- a/test/cuchaz/enigma/inputs/innerClasses/ConstructorArgs.java +++ b/test/cuchaz/enigma/inputs/innerClasses/C_ConstructorArgs.java | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | package cuchaz.enigma.inputs.innerClasses; | 1 | package cuchaz.enigma.inputs.innerClasses; |
| 2 | 2 | ||
| 3 | @SuppressWarnings("unused") | 3 | @SuppressWarnings("unused") |
| 4 | public class ConstructorArgs { | 4 | public class C_ConstructorArgs { |
| 5 | 5 | ||
| 6 | class Inner { | 6 | class Inner { |
| 7 | 7 | ||
diff --git a/test/cuchaz/enigma/inputs/innerClasses/Simple.java b/test/cuchaz/enigma/inputs/innerClasses/D_Simple.java index cb536fa6..c4fc0ef9 100644 --- a/test/cuchaz/enigma/inputs/innerClasses/Simple.java +++ b/test/cuchaz/enigma/inputs/innerClasses/D_Simple.java | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | package cuchaz.enigma.inputs.innerClasses; | 1 | package cuchaz.enigma.inputs.innerClasses; |
| 2 | 2 | ||
| 3 | public class Simple { | 3 | public class D_Simple { |
| 4 | 4 | ||
| 5 | class Inner { | 5 | class Inner { |
| 6 | // nothing to do | 6 | // nothing to do |
diff --git a/test/cuchaz/enigma/inputs/innerClasses/E_AnonymousWithOuterAccess.java b/test/cuchaz/enigma/inputs/innerClasses/E_AnonymousWithOuterAccess.java new file mode 100644 index 00000000..e1de53cb --- /dev/null +++ b/test/cuchaz/enigma/inputs/innerClasses/E_AnonymousWithOuterAccess.java | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | package cuchaz.enigma.inputs.innerClasses; | ||
| 2 | |||
| 3 | public class E_AnonymousWithOuterAccess { | ||
| 4 | |||
| 5 | // reproduction of error case documented at: | ||
| 6 | // https://bitbucket.org/cuchaz/enigma/issue/61/stackoverflowerror-when-deobfuscating | ||
| 7 | |||
| 8 | public Object makeInner() { | ||
| 9 | outerMethod(); | ||
| 10 | return new Object() { | ||
| 11 | @Override | ||
| 12 | public String toString() { | ||
| 13 | return outerMethod(); | ||
| 14 | } | ||
| 15 | }; | ||
| 16 | } | ||
| 17 | |||
| 18 | private String outerMethod() { | ||
| 19 | return "foo"; | ||
| 20 | } | ||
| 21 | } | ||