summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar jeff2014-08-07 00:55:43 -0400
committerGravatar jeff2014-08-07 00:55:43 -0400
commit6aa7c6121a2ecbe78f14f8c3d7ddb55b8ddb10bd (patch)
tree0b97553e42e2e3a52a1aab30914d885d143d5bf0 /src
parentadded un-obfuscated classes to the deobfuscated classes list (diff)
downloadenigma-fork-6aa7c6121a2ecbe78f14f8c3d7ddb55b8ddb10bd.tar.gz
enigma-fork-6aa7c6121a2ecbe78f14f8c3d7ddb55b8ddb10bd.tar.xz
enigma-fork-6aa7c6121a2ecbe78f14f8c3d7ddb55b8ddb10bd.zip
started working on recognition of non-class member identifiers in the source
got class extends,implements working and argument,field types added filtering to make sure highlighted class names are actually classes in the jar
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java87
-rw-r--r--src/cuchaz/enigma/analysis/Analyzer.java91
-rw-r--r--src/cuchaz/enigma/analysis/Lexer.java42
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndex.java34
-rw-r--r--src/cuchaz/enigma/analysis/SourcedAst.java43
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java12
-rw-r--r--src/cuchaz/enigma/gui/SourceFormatter.java62
7 files changed, 223 insertions, 148 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index e067183..e6e647e 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -10,10 +10,12 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma; 11package cuchaz.enigma;
12 12
13import java.io.BufferedReader;
13import java.io.File; 14import java.io.File;
14import java.io.FileInputStream; 15import java.io.FileInputStream;
15import java.io.IOException; 16import java.io.IOException;
16import java.io.InputStream; 17import java.io.InputStream;
18import java.io.StringReader;
17import java.io.StringWriter; 19import java.io.StringWriter;
18import java.util.Enumeration; 20import java.util.Enumeration;
19import java.util.List; 21import java.util.List;
@@ -21,6 +23,7 @@ import java.util.Map;
21import java.util.jar.JarEntry; 23import java.util.jar.JarEntry;
22import java.util.jar.JarFile; 24import java.util.jar.JarFile;
23 25
26import com.beust.jcommander.internal.Lists;
24import com.strobel.decompiler.Decompiler; 27import com.strobel.decompiler.Decompiler;
25import com.strobel.decompiler.DecompilerSettings; 28import com.strobel.decompiler.DecompilerSettings;
26import com.strobel.decompiler.PlainTextOutput; 29import com.strobel.decompiler.PlainTextOutput;
@@ -45,6 +48,7 @@ public class Deobfuscator
45 private Ancestries m_ancestries; 48 private Ancestries m_ancestries;
46 private Mappings m_mappings; 49 private Mappings m_mappings;
47 private Renamer m_renamer; 50 private Renamer m_renamer;
51 private List<String> m_obfClassNames;
48 52
49 public Deobfuscator( File file ) 53 public Deobfuscator( File file )
50 throws IOException 54 throws IOException
@@ -65,6 +69,26 @@ public class Deobfuscator
65 Util.closeQuietly( jarIn ); 69 Util.closeQuietly( jarIn );
66 } 70 }
67 71
72 // get the obf class names
73 m_obfClassNames = Lists.newArrayList();
74 {
75 Enumeration<JarEntry> entries = m_jar.entries();
76 while( entries.hasMoreElements() )
77 {
78 JarEntry entry = entries.nextElement();
79
80 // skip everything but class files
81 if( !entry.getName().endsWith( ".class" ) )
82 {
83 continue;
84 }
85
86 // get the class name from the file
87 String className = entry.getName().substring( 0, entry.getName().length() - 6 );
88 m_obfClassNames.add( className );
89 }
90 }
91
68 // config the decompiler 92 // config the decompiler
69 m_settings = DecompilerSettings.javaDefaults(); 93 m_settings = DecompilerSettings.javaDefaults();
70 m_settings.setForceExplicitImports( true ); 94 m_settings.setForceExplicitImports( true );
@@ -112,20 +136,9 @@ public class Deobfuscator
112 136
113 public void getSeparatedClasses( List<ClassFile> obfClasses, Map<ClassFile,String> deobfClasses ) 137 public void getSeparatedClasses( List<ClassFile> obfClasses, Map<ClassFile,String> deobfClasses )
114 { 138 {
115 Enumeration<JarEntry> entries = m_jar.entries(); 139 for( String obfClassName : m_obfClassNames )
116 while( entries.hasMoreElements() )
117 { 140 {
118 JarEntry entry = entries.nextElement(); 141 ClassFile classFile = new ClassFile( obfClassName );
119
120 // skip everything but class files
121 if( !entry.getName().endsWith( ".class" ) )
122 {
123 continue;
124 }
125
126 // get the class name from the file
127 String className = entry.getName().substring( 0, entry.getName().length() - 6 );
128 ClassFile classFile = new ClassFile( className );
129 142
130 // separate the classes 143 // separate the classes
131 ClassMapping classMapping = m_mappings.getClassByObf( classFile.getName() ); 144 ClassMapping classMapping = m_mappings.getClassByObf( classFile.getName() );
@@ -159,7 +172,41 @@ public class Deobfuscator
159 // decompile it! 172 // decompile it!
160 StringWriter buf = new StringWriter(); 173 StringWriter buf = new StringWriter();
161 Decompiler.decompile( deobfName, new PlainTextOutput( buf ), m_settings ); 174 Decompiler.decompile( deobfName, new PlainTextOutput( buf ), m_settings );
162 return buf.toString(); 175 return fixSource( buf.toString() );
176 }
177
178 private String fixSource( String source )
179 {
180 // fix the imports from the default package in the source
181 try
182 {
183 StringBuilder buf = new StringBuilder();
184 BufferedReader reader = new BufferedReader( new StringReader( source ) );
185 String line = null;
186 while( ( line = reader.readLine() ) != null )
187 {
188 String[] parts = line.trim().split( " " );
189 if( parts.length == 2 && parts[0].equals( "import" ) )
190 {
191 // is this an (illegal) import from the default package?
192 String className = parts[1];
193 if( className.indexOf( '.' ) < 0 )
194 {
195 // this is an illegal import, replace it
196 line = "import __DEFAULT__." + parts[1];
197 }
198 }
199
200 buf.append( line );
201 buf.append( "\n" );
202 }
203 return buf.toString();
204 }
205 catch( IOException ex )
206 {
207 // dealing with IOExceptions on StringReaders is silly...
208 throw new Error( ex );
209 }
163 } 210 }
164 211
165 // NOTE: these methods are a bit messy... oh well 212 // NOTE: these methods are a bit messy... oh well
@@ -265,4 +312,16 @@ public class Deobfuscator
265 throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); 312 throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() );
266 } 313 }
267 } 314 }
315
316 public boolean entryIsObfuscatedIdenfitier( Entry obfEntry )
317 {
318 if( obfEntry instanceof ClassEntry )
319 {
320 // obf classes must be in the list
321 return m_obfClassNames.contains( obfEntry.getName() );
322 }
323
324 // assume everything else is an identifier
325 return true;
326 }
268} 327}
diff --git a/src/cuchaz/enigma/analysis/Analyzer.java b/src/cuchaz/enigma/analysis/Analyzer.java
index dad8dc5..2b7e0b0 100644
--- a/src/cuchaz/enigma/analysis/Analyzer.java
+++ b/src/cuchaz/enigma/analysis/Analyzer.java
@@ -35,6 +35,7 @@ import com.sun.source.util.Trees;
35 35
36import cuchaz.enigma.mapping.ArgumentEntry; 36import cuchaz.enigma.mapping.ArgumentEntry;
37import cuchaz.enigma.mapping.ClassEntry; 37import cuchaz.enigma.mapping.ClassEntry;
38import cuchaz.enigma.mapping.Entry;
38import cuchaz.enigma.mapping.FieldEntry; 39import cuchaz.enigma.mapping.FieldEntry;
39import cuchaz.enigma.mapping.MethodEntry; 40import cuchaz.enigma.mapping.MethodEntry;
40 41
@@ -78,39 +79,31 @@ class TreeVisitor extends TreeScanner<CompilationUnitTree, SourcedAst>
78 79
79 private ClassEntry indexClass( ClassTree classTree, SourcedAst ast ) 80 private ClassEntry indexClass( ClassTree classTree, SourcedAst ast )
80 { 81 {
81 // build the entry 82 // index the class name
82 ClassEntry entry = new ClassEntry( ast.getFullClassName( classTree.getSimpleName().toString() ) ); 83 ClassEntry classEntry = indexClassIdentifier( classTree, ast );
84 assert( classEntry != null );
83 85
84 // lex the source at this tree node 86 // index the extends clause
85 for( Token token : new Lexer( ast.getSource( classTree ).toString() ) ) 87 indexClassIdentifier( classTree.getExtendsClause(), ast );
88
89 // index the implements clauses
90 for( Tree implementsTree : classTree.getImplementsClause() )
86 { 91 {
87 // scan until we get the first identifier 92 indexClassIdentifier( implementsTree, ast );
88 if( token.type == TokenType.IDENTIFIER )
89 {
90 m_index.add( entry, offsetToken( token, ast.getStart( classTree ) ) );
91 break;
92 }
93 } 93 }
94 94
95 return entry; 95 return classEntry;
96 } 96 }
97 97
98 private FieldEntry indexField( VariableTree variableTree, SourcedAst ast, ClassEntry classEntry ) 98 private FieldEntry indexField( VariableTree variableTree, SourcedAst ast, ClassEntry classEntry )
99 { 99 {
100 // build the entry 100 // index the field name
101 FieldEntry entry = new FieldEntry( classEntry, variableTree.getName().toString() ); 101 FieldEntry entry = new FieldEntry( classEntry, variableTree.getName().toString() );
102 Token nameToken = new Lexer( ast.getSource( variableTree ) ).getFirstIdentifierMatching( variableTree.getName() );
103 addToken( entry, nameToken, variableTree, ast );
102 104
103 // lex the source at this tree node 105 // index the field type
104 Lexer lexer = new Lexer( ast.getSource( variableTree ).toString() ); 106 indexClassIdentifier( variableTree.getType(), ast );
105 for( Token token : lexer )
106 {
107 // scan until we find an identifier that matches the field name
108 if( token.type == TokenType.IDENTIFIER && lexer.getText( token ).equals( entry.getName() ) )
109 {
110 m_index.add( entry, offsetToken( token, ast.getStart( variableTree ) ) );
111 break;
112 }
113 }
114 107
115 return entry; 108 return entry;
116 } 109 }
@@ -136,13 +129,13 @@ class TreeVisitor extends TreeScanner<CompilationUnitTree, SourcedAst>
136 MethodEntry entry = new MethodEntry( classEntry, methodTree.getName().toString(), signature.toString() ); 129 MethodEntry entry = new MethodEntry( classEntry, methodTree.getName().toString(), signature.toString() );
137 130
138 // lex the source at this tree node 131 // lex the source at this tree node
139 Lexer lexer = new Lexer( ast.getSource( methodTree ).toString() ); 132 Lexer lexer = new Lexer( ast.getSource( methodTree ) );
140 for( Token token : lexer ) 133 for( Token token : lexer )
141 { 134 {
142 // scan until we find an identifier that matches the method name 135 // scan until we find an identifier that matches the method name
143 if( token.type == TokenType.IDENTIFIER && lexer.getText( token ).equals( entry.getName() ) ) 136 if( token.type == TokenType.IDENTIFIER && lexer.getText( token ).equals( entry.getName() ) )
144 { 137 {
145 m_index.add( entry, offsetToken( token, ast.getStart( methodTree ) ) ); 138 addToken( entry, token, methodTree, ast );
146 break; 139 break;
147 } 140 }
148 } 141 }
@@ -152,27 +145,47 @@ class TreeVisitor extends TreeScanner<CompilationUnitTree, SourcedAst>
152 145
153 private void indexArgument( VariableTree variableTree, SourcedAst ast, MethodEntry methodEntry, int index ) 146 private void indexArgument( VariableTree variableTree, SourcedAst ast, MethodEntry methodEntry, int index )
154 { 147 {
155 // build the entry 148 // index argument name
156 ArgumentEntry entry = new ArgumentEntry( methodEntry, index, variableTree.getName().toString() ); 149 ArgumentEntry entry = new ArgumentEntry( methodEntry, index, variableTree.getName().toString() );
150 Token token = new Lexer( ast.getSource( variableTree ) ).getLastIdentifier();
151 addToken( entry, token, variableTree, ast );
157 152
158 // lex the source at this tree node 153 // index argument type
159 Lexer lexer = new Lexer( ast.getSource( variableTree ).toString() ); 154 indexClassIdentifier( variableTree.getType(), ast );
160 for( Token token : lexer ) 155 }
156
157 private ClassEntry indexClassIdentifier( Tree tree, SourcedAst ast )
158 {
159 if( tree == null )
161 { 160 {
162 // scan until we find an identifier that matches the variable name 161 return null;
163 if( token.type == TokenType.IDENTIFIER && lexer.getText( token ).equals( entry.getName() ) ) 162 }
164 { 163
165 m_index.add( entry, offsetToken( token, ast.getStart( variableTree ) ) ); 164 Lexer lexer = new Lexer( ast.getSource( tree ) );
166 break; 165 Token token = lexer.getFirstIdentifier();
167 } 166 if( token == null )
167 {
168 return null;
168 } 169 }
170
171 ClassEntry classEntry = new ClassEntry( ast.getFullClassName( lexer.getText( token ) ) );
172 addToken( classEntry, token, tree, ast );
173 return classEntry;
169 } 174 }
170 175
171 private Token offsetToken( Token in, int offset ) 176 private void addToken( Entry entry, Token token, Tree tree, SourcedAst ast )
172 { 177 {
173 return new Token( in.type, in.start + offset, in.length ); 178 if( token == null )
179 {
180 throw new IllegalArgumentException( "token cannot be null!" );
181 }
182
183 // offset the token by the tree
184 Token offsetToken = new Token( token.type, token.start + ast.getStart( tree ), token.length );
185
186 m_index.add( entry, offsetToken );
174 } 187 }
175 188
176 private String toJvmType( Tree tree, SourcedAst ast ) 189 private String toJvmType( Tree tree, SourcedAst ast )
177 { 190 {
178 switch( tree.getKind() ) 191 switch( tree.getKind() )
diff --git a/src/cuchaz/enigma/analysis/Lexer.java b/src/cuchaz/enigma/analysis/Lexer.java
index acb52bf..602e3a9 100644
--- a/src/cuchaz/enigma/analysis/Lexer.java
+++ b/src/cuchaz/enigma/analysis/Lexer.java
@@ -14,6 +14,7 @@ import java.util.Iterator;
14 14
15import jsyntaxpane.SyntaxDocument; 15import jsyntaxpane.SyntaxDocument;
16import jsyntaxpane.Token; 16import jsyntaxpane.Token;
17import jsyntaxpane.TokenType;
17import jsyntaxpane.lexers.JavaLexer; 18import jsyntaxpane.lexers.JavaLexer;
18 19
19public class Lexer implements Iterable<Token> 20public class Lexer implements Iterable<Token>
@@ -21,10 +22,10 @@ public class Lexer implements Iterable<Token>
21 private SyntaxDocument m_doc; 22 private SyntaxDocument m_doc;
22 private Iterator<Token> m_iter; 23 private Iterator<Token> m_iter;
23 24
24 public Lexer( String source ) 25 public Lexer( CharSequence source )
25 { 26 {
26 m_doc = new SyntaxDocument( new JavaLexer() ); 27 m_doc = new SyntaxDocument( new JavaLexer() );
27 m_doc.append( source ); 28 m_doc.append( source.toString() );
28 m_iter = m_doc.getTokens( 0, m_doc.getLength() ); 29 m_iter = m_doc.getTokens( 0, m_doc.getLength() );
29 } 30 }
30 31
@@ -38,4 +39,41 @@ public class Lexer implements Iterable<Token>
38 { 39 {
39 return token.getString( m_doc ); 40 return token.getString( m_doc );
40 } 41 }
42
43 public Token getFirstIdentifier( )
44 {
45 for( Token token : this )
46 {
47 if( token.type == TokenType.IDENTIFIER )
48 {
49 return token;
50 }
51 }
52 return null;
53 }
54
55 public Token getFirstIdentifierMatching( CharSequence val )
56 {
57 for( Token token : this )
58 {
59 if( token.type == TokenType.IDENTIFIER && getText( token ).equals( val.toString() ) )
60 {
61 return token;
62 }
63 }
64 return null;
65 }
66
67 public Token getLastIdentifier( )
68 {
69 Token lastToken = null;
70 for( Token token : this )
71 {
72 if( token.type == TokenType.IDENTIFIER )
73 {
74 lastToken = token;
75 }
76 }
77 return lastToken;
78 }
41} 79}
diff --git a/src/cuchaz/enigma/analysis/SourceIndex.java b/src/cuchaz/enigma/analysis/SourceIndex.java
index 61c833c..de16308 100644
--- a/src/cuchaz/enigma/analysis/SourceIndex.java
+++ b/src/cuchaz/enigma/analysis/SourceIndex.java
@@ -10,46 +10,52 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import java.util.Collection;
13import java.util.Iterator; 14import java.util.Iterator;
14import java.util.Map; 15import java.util.Map;
15import java.util.Set;
16 16
17import jsyntaxpane.Token; 17import jsyntaxpane.Token;
18 18
19import com.google.common.collect.BiMap; 19import com.google.common.collect.HashMultimap;
20import com.google.common.collect.HashBiMap; 20import com.google.common.collect.Multimap;
21 21
22import cuchaz.enigma.mapping.Entry; 22import cuchaz.enigma.mapping.Entry;
23 23
24public class SourceIndex implements Iterable<Map.Entry<Entry,Token>> 24public class SourceIndex implements Iterable<Map.Entry<Entry,Token>>
25{ 25{
26 private BiMap<Entry,Token> m_entryToToken; 26 private Multimap<Entry,Token> m_entryToTokens;
27 private BiMap<Token,Entry> m_tokenToEntry;
28 27
29 public SourceIndex( ) 28 public SourceIndex( )
30 { 29 {
31 m_entryToToken = HashBiMap.create(); 30 m_entryToTokens = HashMultimap.create();
32 m_tokenToEntry = m_entryToToken.inverse();
33 } 31 }
34 32
35 public void add( Entry entry, Token token ) 33 public void add( Entry entry, Token token )
36 { 34 {
37 m_entryToToken.put( entry, token ); 35 m_entryToTokens.put( entry, token );
38 } 36 }
39 37
40 public Iterator<Map.Entry<Entry,Token>> iterator( ) 38 public Iterator<Map.Entry<Entry,Token>> iterator( )
41 { 39 {
42 return m_entryToToken.entrySet().iterator(); 40 return m_entryToTokens.entries().iterator();
43 } 41 }
44 42
45 public Set<Token> tokens( ) 43 public Collection<Token> tokens( )
46 { 44 {
47 return m_entryToToken.values(); 45 return m_entryToTokens.values();
48 } 46 }
49 47
50 public Entry getEntry( Token token ) 48 public Entry getEntry( Token token )
51 { 49 {
52 return m_tokenToEntry.get( token ); 50 // linear search is fast enough for now
51 for( Map.Entry<Entry,Token> entry : this )
52 {
53 if( entry.getValue().equals( token ) )
54 {
55 return entry.getKey();
56 }
57 }
58 return null;
53 } 59 }
54 60
55 public Map.Entry<Entry,Token> getEntry( int pos ) 61 public Map.Entry<Entry,Token> getEntry( int pos )
@@ -66,8 +72,8 @@ public class SourceIndex implements Iterable<Map.Entry<Entry,Token>>
66 return null; 72 return null;
67 } 73 }
68 74
69 public Token getToken( Entry entry ) 75 public Collection<Token> getTokens( Entry entry )
70 { 76 {
71 return m_entryToToken.get( entry ); 77 return m_entryToTokens.get( entry );
72 } 78 }
73} 79}
diff --git a/src/cuchaz/enigma/analysis/SourcedAst.java b/src/cuchaz/enigma/analysis/SourcedAst.java
index 968c880..a88cc75 100644
--- a/src/cuchaz/enigma/analysis/SourcedAst.java
+++ b/src/cuchaz/enigma/analysis/SourcedAst.java
@@ -16,7 +16,6 @@ import java.util.HashMap;
16import javassist.bytecode.Descriptor; 16import javassist.bytecode.Descriptor;
17 17
18import com.google.common.collect.Maps; 18import com.google.common.collect.Maps;
19import com.sun.source.tree.ClassTree;
20import com.sun.source.tree.CompilationUnitTree; 19import com.sun.source.tree.CompilationUnitTree;
21import com.sun.source.tree.ImportTree; 20import com.sun.source.tree.ImportTree;
22import com.sun.source.tree.Tree; 21import com.sun.source.tree.Tree;
@@ -29,6 +28,7 @@ public class SourcedAst
29 private Trees m_trees; 28 private Trees m_trees;
30 private SourcePositions m_positions; 29 private SourcePositions m_positions;
31 private HashMap<String,String> m_classNameIndex; 30 private HashMap<String,String> m_classNameIndex;
31 private String m_packageName;
32 32
33 public SourcedAst( CompilationUnitTree tree, Trees trees ) 33 public SourcedAst( CompilationUnitTree tree, Trees trees )
34 { 34 {
@@ -49,6 +49,13 @@ public class SourcedAst
49 // get the full and simple class names 49 // get the full and simple class names
50 String fullName = Descriptor.toJvmName( importTree.getQualifiedIdentifier().toString() ); 50 String fullName = Descriptor.toJvmName( importTree.getQualifiedIdentifier().toString() );
51 String simpleName = fullName; 51 String simpleName = fullName;
52
53 if( fullName.startsWith( "__DEFAULT__/" ) )
54 {
55 // remove the default package flag
56 fullName = fullName.substring( 12 );
57 }
58
52 String[] parts = fullName.split( "/" ); 59 String[] parts = fullName.split( "/" );
53 if( parts.length > 0 ) 60 if( parts.length > 0 )
54 { 61 {
@@ -58,30 +65,26 @@ public class SourcedAst
58 m_classNameIndex.put( simpleName, fullName ); 65 m_classNameIndex.put( simpleName, fullName );
59 } 66 }
60 67
61 // index the self class using the package name 68 // get the package name
69 m_packageName = null;
62 if( m_tree.getPackageName() != null ) 70 if( m_tree.getPackageName() != null )
63 { 71 {
64 String packageName = Descriptor.toJvmName( m_tree.getPackageName().toString() ); 72 m_packageName = Descriptor.toJvmName( m_tree.getPackageName().toString() );
65 for( Tree typeTree : m_tree.getTypeDecls() )
66 {
67 if( typeTree instanceof ClassTree )
68 {
69 ClassTree classTree = (ClassTree)typeTree;
70 String className = classTree.getSimpleName().toString();
71 m_classNameIndex.put( className, packageName + "/" + className );
72 }
73 }
74 } 73 }
75 } 74 }
76 75
77 public int getStart( Tree node ) 76 public int getStart( Tree node )
78 { 77 {
79 return (int)m_positions.getStartPosition( m_tree, node ); 78 int pos = (int)m_positions.getStartPosition( m_tree, node );
79 assert( pos >= 0 );
80 return pos;
80 } 81 }
81 82
82 public int getEnd( Tree node ) 83 public int getEnd( Tree node )
83 { 84 {
84 return (int)m_positions.getEndPosition( m_tree, node ); 85 int pos = (int)m_positions.getEndPosition( m_tree, node );
86 assert( pos >= 0 );
87 return pos;
85 } 88 }
86 89
87 public int getLine( Tree node ) 90 public int getLine( Tree node )
@@ -121,8 +124,16 @@ public class SourcedAst
121 String fullClassName = m_classNameIndex.get( simpleClassName ); 124 String fullClassName = m_classNameIndex.get( simpleClassName );
122 if( fullClassName == null ) 125 if( fullClassName == null )
123 { 126 {
124 // no mapping was found, the name is probably already fully-qualified 127 if( m_packageName != null )
125 fullClassName = simpleClassName; 128 {
129 // no mapping was found, assume it's in the package
130 fullClassName = m_packageName + "/" + simpleClassName;
131 }
132 else
133 {
134 // this must be in the default package
135 fullClassName = simpleClassName;
136 }
126 } 137 }
127 return fullClassName; 138 return fullClassName;
128 } 139 }
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index 7d37feb..2219e05 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -132,6 +132,16 @@ public class GuiController
132 return m_deobfuscator.hasMapping( pair.obf ); 132 return m_deobfuscator.hasMapping( pair.obf );
133 } 133 }
134 134
135 public boolean entryIsObfuscatedIdenfitier( int pos )
136 {
137 EntryPair<Entry> pair = getEntryPair( pos );
138 if( pair == null || pair.obf == null )
139 {
140 return false;
141 }
142 return m_deobfuscator.entryIsObfuscatedIdenfitier( pair.obf );
143 }
144
135 public ClassInheritanceTreeNode getClassInheritance( ClassEntry classEntry ) 145 public ClassInheritanceTreeNode getClassInheritance( ClassEntry classEntry )
136 { 146 {
137 Translator deobfuscatingTranslator = m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ); 147 Translator deobfuscatingTranslator = m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating );
@@ -216,7 +226,7 @@ public class GuiController
216 { 226 {
217 deobfuscatedTokens.add( token ); 227 deobfuscatedTokens.add( token );
218 } 228 }
219 else 229 else if( entryIsObfuscatedIdenfitier( token.start ) )
220 { 230 {
221 obfuscatedTokens.add( token ); 231 obfuscatedTokens.add( token );
222 } 232 }
diff --git a/src/cuchaz/enigma/gui/SourceFormatter.java b/src/cuchaz/enigma/gui/SourceFormatter.java
deleted file mode 100644
index f387840..0000000
--- a/src/cuchaz/enigma/gui/SourceFormatter.java
+++ /dev/null
@@ -1,62 +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 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import java.io.BufferedReader;
14import java.io.IOException;
15import java.io.StringReader;
16
17public class SourceFormatter
18{
19 public static String format( String in )
20 {
21 return collapseNewlines( in );
22 }
23
24 private static String collapseNewlines( String in )
25 {
26 StringBuffer buf = new StringBuffer();
27 int numBlankLines = 0;
28
29 BufferedReader reader = new BufferedReader( new StringReader( in ) );
30 String line = null;
31 try
32 {
33 while( ( line = reader.readLine() ) != null )
34 {
35 // how blank lines is this?
36 boolean isBlank = line.trim().length() == 0;
37 if( isBlank )
38 {
39 numBlankLines++;
40
41 // stop printing blank lines after the first one
42 if( numBlankLines < 2 )
43 {
44 buf.append( line );
45 buf.append( "\n" );
46 }
47 }
48 else
49 {
50 numBlankLines = 0;
51 buf.append( line );
52 buf.append( "\n" );
53 }
54 }
55 }
56 catch( IOException ex )
57 {
58 // StringReader will never throw an IOExecption here...
59 }
60 return buf.toString();
61 }
62}