Skip to content

Commit 1ac293c

Browse files
committed
Procyon Decompiler Update
1 parent edd09c0 commit 1ac293c

1 file changed

Lines changed: 93 additions & 86 deletions

File tree

src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java

Lines changed: 93 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.strobel.decompiler.languages.java.JavaFormattingOptions;
2828
import org.objectweb.asm.tree.ClassNode;
2929
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
30+
import the.bytecode.club.bytecodeviewer.Constants;
3031
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
3132
import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler;
3233
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
@@ -42,21 +43,21 @@
4243
import java.util.zip.ZipOutputStream;
4344

4445
import static the.bytecode.club.bytecodeviewer.Constants.*;
45-
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
46-
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.PROCYON;
46+
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*;
4747

4848
/**
4949
* Procyon Java Decompiler Wrapper
5050
*
5151
* @author Konloch
5252
* @author DeathMarine
5353
*/
54+
5455
public class ProcyonDecompiler extends AbstractDecompiler
5556
{
5657

5758
public ProcyonDecompiler()
5859
{
59-
super("Procyon Decompiler", "proycon");
60+
super("Procyon Decompiler", "procyon");
6061
}
6162

6263
@Override
@@ -69,34 +70,43 @@ public String decompileClassNode(ClassNode cn, byte[] bytes)
6970
{
7071
//create the temporary files
7172
tempFile = TempFile.createTemporaryFile(false, ".class");
72-
File tempClassFile = tempFile.getFile();
73+
File tempInputClassFile = tempFile.getFile();
7374

7475
//write the ClassNode bytes to the temp file
75-
try (FileOutputStream fos = new FileOutputStream(tempClassFile))
76+
try (FileOutputStream fos = new FileOutputStream(tempInputClassFile))
7677
{
7778
fos.write(bytes);
7879
}
7980

80-
//setup proycon decompiler settings
81+
//initialize procyon
8182
DecompilerSettings settings = getDecompilerSettings();
82-
8383
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
8484
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
85-
TypeReference type = metadataSystem.lookupType(tempClassFile.getCanonicalPath());
86-
8785
DecompilationOptions decompilationOptions = new DecompilationOptions();
86+
StringWriter writer = new StringWriter();
87+
88+
//lookup the class-file
89+
TypeReference type = metadataSystem.lookupType(tempInputClassFile.getCanonicalPath());
90+
91+
//configure procyon
8892
decompilationOptions.setSettings(settings);
8993
decompilationOptions.setFullDecompilation(true);
9094

95+
//parse class-file
9196
TypeDefinition resolvedType;
9297

9398
if (type == null || ((resolvedType = type.resolve()) == null))
94-
throw new Exception("Unable to resolve type.");
99+
throw new Exception("Unable to resolve class-filetype.");
100+
101+
//decompile the class-file
102+
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
95103

96-
StringWriter stringwriter = new StringWriter();
97-
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions);
104+
//handle simulated errors
105+
if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS)
106+
throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString());
98107

99-
return EncodeUtils.unicodeToString(stringwriter.toString());
108+
//return the writer contents
109+
return EncodeUtils.unicodeToString(writer.toString());
100110
}
101111
catch (Throwable e)
102112
{
@@ -106,7 +116,7 @@ public String decompileClassNode(ClassNode cn, byte[] bytes)
106116
{
107117
//delete all temporary files
108118
if(tempFile != null)
109-
tempFile.delete();
119+
tempFile.cleanup();
110120
}
111121

112122
return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL
@@ -118,108 +128,105 @@ public void decompileToZip(String sourceJar, String zipName)
118128
{
119129
try
120130
{
121-
doSaveJarDecompiled(new File(sourceJar), new File(zipName));
122-
}
123-
catch (StackOverflowError | Exception e)
124-
{
125-
BytecodeViewer.handleException(e);
126-
}
127-
}
131+
try (JarFile jarFile = new JarFile(sourceJar);
132+
FileOutputStream destination = new FileOutputStream(zipName);
133+
BufferedOutputStream buffer = new BufferedOutputStream(destination);
134+
ZipOutputStream zip = new ZipOutputStream(buffer))
135+
{
136+
byte[] data = new byte[1024];
128137

129-
/**
130-
* @author DeathMarine
131-
*/
132-
private void doSaveJarDecompiled(File inFile, File outFile) throws Exception
133-
{
134-
try (JarFile jfile = new JarFile(inFile);
135-
FileOutputStream dest = new FileOutputStream(outFile);
136-
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
137-
ZipOutputStream out = new ZipOutputStream(buffDest))
138-
{
139-
byte[] data = new byte[1024];
140-
DecompilerSettings settings = getDecompilerSettings();
141-
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
142-
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
143-
ITypeLoader jarLoader = new JarTypeLoader(jfile);
144-
typeLoader.getTypeLoaders().add(jarLoader);
138+
//initialize procyon
139+
DecompilerSettings settings = getDecompilerSettings();
140+
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
141+
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
142+
ITypeLoader jarLoader = new JarTypeLoader(jarFile);
145143

146-
DecompilationOptions decompilationOptions = new DecompilationOptions();
147-
decompilationOptions.setSettings(settings);
148-
decompilationOptions.setFullDecompilation(true);
144+
//lookup the jar-file
145+
typeLoader.getTypeLoaders().add(jarLoader);
149146

150-
Enumeration<JarEntry> ent = jfile.entries();
151-
Set<JarEntry> history = new HashSet<>();
147+
//configure procyon
148+
DecompilationOptions decompilationOptions = new DecompilationOptions();
149+
decompilationOptions.setSettings(settings);
150+
decompilationOptions.setFullDecompilation(true);
152151

153-
while (ent.hasMoreElements())
154-
{
155-
JarEntry entry = ent.nextElement();
152+
//setup jar output
153+
Enumeration<JarEntry> ent = jarFile.entries();
154+
Set<JarEntry> history = new HashSet<>();
156155

157-
if (entry.getName().endsWith(".class"))
156+
while (ent.hasMoreElements())
158157
{
159-
JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java"));
158+
JarEntry entry = ent.nextElement();
160159

161-
if (history.add(etn))
160+
if (entry.getName().endsWith(".class"))
162161
{
163-
out.putNextEntry(etn);
162+
JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java"));
164163

165-
try
164+
if (history.add(etn))
166165
{
167-
String internalName = StringUtilities.removeRight(entry.getName(), ".class");
168-
TypeReference type = metadataSystem.lookupType(internalName);
169-
TypeDefinition resolvedType;
166+
zip.putNextEntry(etn);
170167

171-
if ((type == null) || ((resolvedType = type.resolve()) == null))
168+
try
172169
{
173-
throw new Exception("Unable to resolve type.");
174-
}
170+
String internalName = StringUtilities.removeRight(entry.getName(), ".class");
171+
TypeReference type = metadataSystem.lookupType(internalName);
172+
TypeDefinition resolvedType;
175173

176-
Writer writer = new OutputStreamWriter(out);
177-
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
178-
writer.flush();
179-
}
180-
finally
181-
{
182-
out.closeEntry();
174+
if ((type == null) || ((resolvedType = type.resolve()) == null))
175+
throw new Exception("Unable to resolve type.");
176+
177+
Writer writer = new OutputStreamWriter(zip);
178+
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
179+
writer.flush();
180+
}
181+
finally
182+
{
183+
zip.closeEntry();
184+
}
183185
}
184186
}
185-
}
186-
else
187-
{
188-
try
187+
else
189188
{
190-
JarEntry etn = new JarEntry(entry.getName());
189+
try
190+
{
191+
JarEntry etn = new JarEntry(entry.getName());
191192

192-
if (history.add(etn))
193-
continue;
193+
if (history.add(etn))
194+
continue;
194195

195-
history.add(etn);
196-
out.putNextEntry(etn);
196+
history.add(etn);
197+
zip.putNextEntry(etn);
197198

198-
try (InputStream in = jfile.getInputStream(entry))
199-
{
200-
if (in != null)
199+
try (InputStream in = jarFile.getInputStream(entry))
201200
{
202-
int count;
203-
while ((count = in.read(data, 0, 1024)) != -1)
201+
if (in != null)
204202
{
205-
out.write(data, 0, count);
203+
int count;
204+
205+
while ((count = in.read(data, 0, 1024)) != -1)
206+
{
207+
zip.write(data, 0, count);
208+
}
206209
}
207210
}
211+
finally
212+
{
213+
zip.closeEntry();
214+
}
208215
}
209-
finally
216+
catch (ZipException ze)
210217
{
211-
out.closeEntry();
218+
// some jars contain duplicate pom.xml entries: ignore it
219+
if (!ze.getMessage().contains("duplicate"))
220+
throw ze;
212221
}
213222
}
214-
catch (ZipException ze)
215-
{
216-
// some jars contain duplicate pom.xml entries: ignore it
217-
if (!ze.getMessage().contains("duplicate"))
218-
throw ze;
219-
}
220223
}
221224
}
222225
}
226+
catch (StackOverflowError | Exception e)
227+
{
228+
BytecodeViewer.handleException(e);
229+
}
223230
}
224231

225232
public DecompilerSettings getDecompilerSettings()

0 commit comments

Comments
 (0)