Merge pull request #400 from GraxCode/cfr
Use the CFR API instead of old buggy method.
This commit is contained in:
commit
14a0bd8cb2
1 changed files with 180 additions and 306 deletions
|
@ -1,32 +1,31 @@
|
||||||
package the.bytecode.club.bytecodeviewer.decompilers.impl;
|
package the.bytecode.club.bytecodeviewer.decompilers.impl;
|
||||||
|
|
||||||
import java.io.File;
|
import com.strobel.core.StringUtilities;
|
||||||
import java.io.FileInputStream;
|
import org.apache.commons.io.IOUtils;
|
||||||
import java.io.FileOutputStream;
|
import org.benf.cfr.reader.api.CfrDriver;
|
||||||
import java.io.IOException;
|
import org.benf.cfr.reader.api.ClassFileSource;
|
||||||
import java.io.InputStream;
|
import org.benf.cfr.reader.api.OutputSinkFactory;
|
||||||
import java.io.OutputStream;
|
import org.benf.cfr.reader.api.SinkReturns;
|
||||||
import java.io.PrintWriter;
|
import org.benf.cfr.reader.bytecode.analysis.parse.utils.Pair;
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.Deque;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
import me.konloch.kontainer.io.DiskReader;
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.api.ASMUtil;
|
||||||
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
||||||
import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
|
import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
|
||||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.fs;
|
import java.io.*;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.zip.ZipException;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.nl;
|
import static the.bytecode.club.bytecodeviewer.Constants.nl;
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
|
|
||||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.CFR;
|
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.CFR;
|
||||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
|
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||||
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
||||||
|
@ -48,313 +47,188 @@ import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERR
|
||||||
/**
|
/**
|
||||||
* CFR Java Wrapper
|
* CFR Java Wrapper
|
||||||
*
|
*
|
||||||
* @author Konloch
|
* @author GraxCode
|
||||||
|
* Taken mostly out of Threadtear.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class CFRDecompiler extends InternalDecompiler
|
public class CFRDecompiler extends InternalDecompiler {
|
||||||
{
|
|
||||||
|
|
||||||
private static final String[] WINDOWS_IS_GREAT = new String[]
|
private String result;
|
||||||
{
|
private static final String CLASS_SUFFIX = ".class";
|
||||||
"CON",
|
|
||||||
"PRN",
|
|
||||||
"AUX",
|
|
||||||
"NUL",
|
|
||||||
"COM1",
|
|
||||||
"COM2",
|
|
||||||
"COM3",
|
|
||||||
"COM4",
|
|
||||||
"COM5",
|
|
||||||
"COM6",
|
|
||||||
"COM7",
|
|
||||||
"COM8",
|
|
||||||
"COM9",
|
|
||||||
"LPT1",
|
|
||||||
"LPT2",
|
|
||||||
"LPT3",
|
|
||||||
"LPT4",
|
|
||||||
"LPT5",
|
|
||||||
"LPT6",
|
|
||||||
"LPT7",
|
|
||||||
"LPT8",
|
|
||||||
"LPT9"
|
|
||||||
};
|
|
||||||
|
|
||||||
public static String windowsFun(String base) {
|
@Override
|
||||||
for (String s : WINDOWS_IS_GREAT) {
|
public String decompileClassNode(ClassNode cn, byte[] bytes) {
|
||||||
if (base.contains(s.toLowerCase())) {
|
String name = cn.name;
|
||||||
base = base.replace(s.toLowerCase(), "BCV");
|
return decompile(bytes, name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return base;
|
private String decompile(byte[] bytes, String name) {
|
||||||
|
try {
|
||||||
|
this.result = null;
|
||||||
|
OutputSinkFactory mySink = new OutputSinkFactory() {
|
||||||
|
@Override
|
||||||
|
public List<SinkClass> getSupportedSinks(SinkType sinkType, Collection<SinkClass> collection) {
|
||||||
|
if (sinkType == SinkType.JAVA && collection.contains(SinkClass.DECOMPILED)) {
|
||||||
|
return Arrays.asList(SinkClass.DECOMPILED, SinkClass.STRING);
|
||||||
|
} else {
|
||||||
|
return Collections.singletonList(SinkClass.STRING);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String decompileClassNode(ClassNode cn, byte[] b) {
|
public <T> Sink<T> getSink(SinkType sinkType, SinkClass sinkClass) {
|
||||||
String fileStart = tempDirectory + fs.toLowerCase();
|
if (sinkType == SinkType.JAVA && sinkClass == SinkClass.DECOMPILED) {
|
||||||
|
return x -> result = ((SinkReturns.Decompiled) x).getJava();
|
||||||
String exception = "";
|
}
|
||||||
//final File tempClass = new File(windowsFun(MiscUtils.getUniqueName(fileStart, ".class") + ".class"));
|
return ignore -> {
|
||||||
final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
|
};
|
||||||
|
}
|
||||||
try (FileOutputStream fos = new FileOutputStream(tempClass)) {
|
};
|
||||||
fos.write(b);
|
ClassFileSource source = new ClassFileSource() {
|
||||||
} catch (final IOException e) {
|
@Override
|
||||||
BytecodeViewer.handleException(e);
|
public void informAnalysisRelativePathDetail(String a, String b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String fuckery = fuckery(fileStart);
|
@Override
|
||||||
|
public String getPossiblyRenamedPath(String path) {
|
||||||
/*if (!BytecodeViewer.fatJar) {
|
return path;
|
||||||
try {
|
|
||||||
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
|
|
||||||
new String[]{BytecodeViewer.getJavaCommand(), "-jar", Resources.findLibrary("cfr")},
|
|
||||||
generateMainMethod(tempClass.getAbsolutePath(), fuckery)
|
|
||||||
));
|
|
||||||
BytecodeViewer.sm.stopBlocking();
|
|
||||||
Process p = pb.start();
|
|
||||||
BytecodeViewer.createdProcesses.add(p);
|
|
||||||
p.waitFor();
|
|
||||||
} catch (Exception e) {
|
|
||||||
BytecodeViewer.handleException(e);
|
|
||||||
} finally {
|
|
||||||
BytecodeViewer.sm.setBlocking();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
org.benf.cfr.reader.Main.main(generateMainMethod(tempClass.getAbsolutePath(), fuckery));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
try {
|
|
||||||
org.benf.cfr.reader.Main.main(generateMainMethod(tempClass.getAbsolutePath(), fuckery));
|
|
||||||
} catch (StackOverflowError | Exception e) {
|
|
||||||
StringWriter exceptionWriter = new StringWriter();
|
|
||||||
e.printStackTrace(new PrintWriter(exceptionWriter));
|
|
||||||
e.printStackTrace();
|
|
||||||
exception = exceptionWriter.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tempClass.delete();
|
@Override
|
||||||
File file = new File(fuckery);
|
public Pair<byte[], String> getClassFileContent(String path) throws IOException {
|
||||||
|
String clzName = path.substring(0, path.length() - 6);
|
||||||
if (file.exists())
|
if (clzName.equals(name)) {
|
||||||
return findFile(MiscUtils.listFiles(file));
|
return Pair.make(bytes, clzName);
|
||||||
|
}
|
||||||
return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
|
URL url = CFRDecompiler.class.getResource("/" + path);
|
||||||
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
|
if (url != null) {
|
||||||
nl + nl + exception;
|
return Pair.make(IOUtils.toByteArray(url), path);
|
||||||
|
}
|
||||||
|
// don't load extra classes. we don't care about improper API usage.
|
||||||
|
ClassNode dummy = new ClassNode();
|
||||||
|
dummy.name = clzName;
|
||||||
|
dummy.version = 52;
|
||||||
|
return Pair.make(ASMUtil.nodeToBytes(dummy), clzName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Random r = new Random();
|
@Override
|
||||||
File f;
|
public Collection<String> addJar(String arg0) {
|
||||||
|
throw new RuntimeException("This should not be called");
|
||||||
public String fuckery(String start) {
|
|
||||||
while (true) {
|
|
||||||
f = new File(start + r.nextInt(Integer.MAX_VALUE));
|
|
||||||
if (!f.exists())
|
|
||||||
return f.toString();
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
CfrDriver cfrDriver = new CfrDriver.Builder().withClassFileSource(source).withOutputSink(mySink).withOptions(generateOptions()).build();
|
||||||
|
cfrDriver.analyse(Collections.singletonList(name));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
t.printStackTrace(pw);
|
||||||
|
return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + sw;
|
||||||
|
}
|
||||||
|
if (result != null && !result.trim().isEmpty()) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String findFile(File[] fA) {
|
return "No CFR output received.";
|
||||||
for (File f : fA) {
|
|
||||||
if (f.isDirectory())
|
|
||||||
return findFile(MiscUtils.listFiles(f));
|
|
||||||
else {
|
|
||||||
String s;
|
|
||||||
try {
|
|
||||||
s = DiskReader.loadAsString(f.getAbsolutePath());
|
|
||||||
} catch (Exception e) {
|
|
||||||
StringWriter exceptionWriter = new StringWriter();
|
|
||||||
e.printStackTrace(new PrintWriter(exceptionWriter));
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
|
|
||||||
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
|
|
||||||
nl + nl + exceptionWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "CFR error!" +
|
|
||||||
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] generateMainMethod(String filePath, String outputPath) {
|
|
||||||
return new String[]{
|
|
||||||
filePath,
|
|
||||||
"--outputdir",
|
|
||||||
outputPath,
|
|
||||||
"--decodeenumswitch",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.decodeEnumSwitch
|
|
||||||
.isSelected()),
|
|
||||||
"--sugarenums",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.sugarEnums.isSelected()),
|
|
||||||
"--decodestringswitch",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.decodeStringSwitch
|
|
||||||
.isSelected()),
|
|
||||||
"--arrayiter",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()),
|
|
||||||
"--collectioniter",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.collectioniter
|
|
||||||
.isSelected()),
|
|
||||||
"--innerclasses",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.innerClasses.isSelected()),
|
|
||||||
"--removeboilerplate",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.removeBoilerPlate
|
|
||||||
.isSelected()),
|
|
||||||
"--removeinnerclasssynthetics",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.removeInnerClassSynthetics
|
|
||||||
.isSelected()),
|
|
||||||
"--decodelambdas",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.decodeLambdas.isSelected()),
|
|
||||||
"--hidebridgemethods",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.hideBridgeMethods
|
|
||||||
.isSelected()),
|
|
||||||
"--liftconstructorinit",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.liftConstructorInit
|
|
||||||
.isSelected()),
|
|
||||||
"--removedeadmethods",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.removeDeadMethods
|
|
||||||
.isSelected()),
|
|
||||||
"--removebadgenerics",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.removeBadGenerics
|
|
||||||
.isSelected()),
|
|
||||||
"--sugarasserts",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.sugarAsserts.isSelected()),
|
|
||||||
"--sugarboxing",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.sugarBoxing.isSelected()),
|
|
||||||
"--showversion",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.showVersion.isSelected()),
|
|
||||||
"--decodefinally",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.decodeFinally.isSelected()),
|
|
||||||
"--tidymonitors",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.tidyMonitors.isSelected()),
|
|
||||||
"--lenient",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.lenient.isSelected()),
|
|
||||||
"--dumpclasspath",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.dumpClassPath.isSelected()),
|
|
||||||
"--comments",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.comments.isSelected()),
|
|
||||||
"--forcetopsort",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.forceTopSort.isSelected()),
|
|
||||||
"--forcetopsortaggress",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.forceTopSortAggress
|
|
||||||
.isSelected()),
|
|
||||||
"--stringbuffer",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.stringBuffer.isSelected()),
|
|
||||||
"--stringbuilder",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.stringBuilder.isSelected()),
|
|
||||||
"--silent",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.silent.isSelected()),
|
|
||||||
"--recover",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.recover.isSelected()),
|
|
||||||
"--eclipse",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()),
|
|
||||||
"--override",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.override.isSelected()),
|
|
||||||
"--showinferrable",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.showInferrable
|
|
||||||
.isSelected()),
|
|
||||||
"--aexagg",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()),
|
|
||||||
"--forcecondpropagate",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.forceCondPropagate
|
|
||||||
.isSelected()),
|
|
||||||
"--hideutf",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.hideUTF.isSelected()),
|
|
||||||
"--hidelongstrings",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.hideLongStrings
|
|
||||||
.isSelected()),
|
|
||||||
"--commentmonitors",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.commentMonitor
|
|
||||||
.isSelected()),
|
|
||||||
"--allowcorrecting",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.allowCorrecting
|
|
||||||
.isSelected()),
|
|
||||||
"--labelledblocks",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.labelledBlocks
|
|
||||||
.isSelected()),
|
|
||||||
"--j14classobj",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.j14ClassOBJ.isSelected()),
|
|
||||||
"--hidelangimports",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.hideLangImports
|
|
||||||
.isSelected()),
|
|
||||||
"--recovertypeclash",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.recoveryTypeClash
|
|
||||||
.isSelected()),
|
|
||||||
"--recovertypehints",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.recoveryTypehInts
|
|
||||||
.isSelected()),
|
|
||||||
"--forcereturningifs",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.forceTurningIFs
|
|
||||||
.isSelected()),
|
|
||||||
"--forloopaggcapture",
|
|
||||||
String.valueOf(BytecodeViewer.viewer.forLoopAGGCapture
|
|
||||||
.isSelected()),};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decompileToZip(String sourceJar, String zipName) {
|
public void decompileToZip(String sourceJar, String zipName) {
|
||||||
File tempZip = new File(sourceJar);
|
|
||||||
|
|
||||||
String fileStart = tempDirectory + fs;
|
|
||||||
String fuckery = fuckery(fileStart);
|
|
||||||
|
|
||||||
org.benf.cfr.reader.Main.main(generateMainMethod(tempZip.getAbsolutePath(), fuckery));
|
|
||||||
|
|
||||||
File fuck = new File(fuckery);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
zip(fuck, new File(zipName));
|
doSaveJarDecompiled(new File(sourceJar), new File(zipName));
|
||||||
} catch (IOException e) {
|
} catch (StackOverflowError | Exception e) {
|
||||||
BytecodeViewer.handleException(e);
|
BytecodeViewer.handleException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuck.delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void zip(File directory, File zipFile) throws IOException {
|
private void doSaveJarDecompiled(File inFile, File outFile) throws IOException {
|
||||||
java.net.URI base = directory.toURI();
|
try (JarFile jfile = new JarFile(inFile); FileOutputStream dest = new FileOutputStream(outFile); BufferedOutputStream buffDest = new BufferedOutputStream(dest); ZipOutputStream out = new ZipOutputStream(buffDest)) {
|
||||||
Deque<File> queue = new LinkedList<>();
|
byte[] data = new byte[1024];
|
||||||
queue.push(directory);
|
|
||||||
try (OutputStream out = new FileOutputStream(zipFile);
|
Enumeration<JarEntry> ent = jfile.entries();
|
||||||
ZipOutputStream zout = new ZipOutputStream(out)) {
|
Set<JarEntry> history = new HashSet<>();
|
||||||
while (!queue.isEmpty()) {
|
while (ent.hasMoreElements()) {
|
||||||
directory = queue.pop();
|
JarEntry entry = ent.nextElement();
|
||||||
for (File kid : MiscUtils.listFiles(directory)) {
|
if (entry.getName().endsWith(CLASS_SUFFIX)) {
|
||||||
String name = base.relativize(kid.toURI()).getPath();
|
JarEntry etn = new JarEntry(entry.getName().replace(CLASS_SUFFIX, ".java"));
|
||||||
if (kid.isDirectory()) {
|
if (history.add(etn)) {
|
||||||
queue.push(kid);
|
out.putNextEntry(etn);
|
||||||
name = name.endsWith("/") ? name : name + "/";
|
try {
|
||||||
zout.putNextEntry(new ZipEntry(name));
|
String internalName = StringUtilities.removeRight(entry.getName(), CLASS_SUFFIX);
|
||||||
|
IOUtils.write(decompile(IOUtils.toByteArray(jfile.getInputStream(entry)), internalName), out, StandardCharsets.UTF_8);
|
||||||
|
} finally {
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
zout.putNextEntry(new ZipEntry(name));
|
try {
|
||||||
copy(kid, zout);
|
JarEntry etn = new JarEntry(entry.getName());
|
||||||
zout.closeEntry();
|
if (history.add(etn)) continue;
|
||||||
|
history.add(etn);
|
||||||
|
out.putNextEntry(etn);
|
||||||
|
try (InputStream in = jfile.getInputStream(entry)) {
|
||||||
|
if (in != null) {
|
||||||
|
int count;
|
||||||
|
while ((count = in.read(data, 0, 1024)) != -1) {
|
||||||
|
out.write(data, 0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
|
} catch (ZipException ze) {
|
||||||
|
// some jars contain duplicate pom.xml entries: ignore it
|
||||||
|
if (!ze.getMessage().contains("duplicate")) {
|
||||||
|
throw ze;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void copy(InputStream in, OutputStream out)
|
private Map<String, String> generateOptions() {
|
||||||
throws IOException {
|
Map<String, String> options = new HashMap<>();
|
||||||
byte[] buffer = new byte[1024];
|
options.put("decodeenumswitch", String.valueOf(BytecodeViewer.viewer.decodeEnumSwitch.isSelected()));
|
||||||
while (true) {
|
options.put("sugarenums", String.valueOf(BytecodeViewer.viewer.sugarEnums.isSelected()));
|
||||||
int readCount = in.read(buffer);
|
options.put("decodestringswitch", String.valueOf(BytecodeViewer.viewer.decodeStringSwitch.isSelected()));
|
||||||
if (readCount < 0) {
|
options.put("arrayiter", String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()));
|
||||||
break;
|
options.put("collectioniter", String.valueOf(BytecodeViewer.viewer.collectioniter.isSelected()));
|
||||||
}
|
options.put("innerclasses", String.valueOf(BytecodeViewer.viewer.innerClasses.isSelected()));
|
||||||
out.write(buffer, 0, readCount);
|
options.put("removeboilerplate", String.valueOf(BytecodeViewer.viewer.removeBoilerPlate.isSelected()));
|
||||||
}
|
options.put("removeinnerclasssynthetics", String.valueOf(BytecodeViewer.viewer.removeInnerClassSynthetics.isSelected()));
|
||||||
}
|
options.put("decodelambdas", String.valueOf(BytecodeViewer.viewer.decodeLambdas.isSelected()));
|
||||||
|
options.put("hidebridgemethods", String.valueOf(BytecodeViewer.viewer.hideBridgeMethods.isSelected()));
|
||||||
private static void copy(File file, OutputStream out) throws IOException {
|
options.put("liftconstructorinit", String.valueOf(BytecodeViewer.viewer.liftConstructorInit.isSelected()));
|
||||||
try (InputStream in = new FileInputStream(file)) {
|
options.put("removebadgenerics", String.valueOf(BytecodeViewer.viewer.removeBadGenerics.isSelected()));
|
||||||
copy(in, out);
|
options.put("sugarasserts", String.valueOf(BytecodeViewer.viewer.sugarAsserts.isSelected()));
|
||||||
}
|
options.put("sugarboxing", String.valueOf(BytecodeViewer.viewer.sugarBoxing.isSelected()));
|
||||||
|
options.put("showversion", String.valueOf(BytecodeViewer.viewer.showVersion.isSelected()));
|
||||||
|
options.put("decodefinally", String.valueOf(BytecodeViewer.viewer.decodeFinally.isSelected()));
|
||||||
|
options.put("tidymonitors", String.valueOf(BytecodeViewer.viewer.tidyMonitors.isSelected()));
|
||||||
|
options.put("lenient", String.valueOf(BytecodeViewer.viewer.lenient.isSelected()));
|
||||||
|
options.put("dumpclasspath", String.valueOf(BytecodeViewer.viewer.dumpClassPath.isSelected()));
|
||||||
|
options.put("comments", String.valueOf(BytecodeViewer.viewer.comments.isSelected()));
|
||||||
|
options.put("forcetopsort", String.valueOf(BytecodeViewer.viewer.forceTopSort.isSelected()));
|
||||||
|
options.put("forcetopsortaggress", String.valueOf(BytecodeViewer.viewer.forceTopSortAggress.isSelected()));
|
||||||
|
options.put("stringbuffer", String.valueOf(BytecodeViewer.viewer.stringBuffer.isSelected()));
|
||||||
|
options.put("stringbuilder", String.valueOf(BytecodeViewer.viewer.stringBuilder.isSelected()));
|
||||||
|
options.put("silent", String.valueOf(BytecodeViewer.viewer.silent.isSelected()));
|
||||||
|
options.put("recover", String.valueOf(BytecodeViewer.viewer.recover.isSelected()));
|
||||||
|
options.put("eclipse", String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()));
|
||||||
|
options.put("override", String.valueOf(BytecodeViewer.viewer.override.isSelected()));
|
||||||
|
options.put("showinferrable", String.valueOf(BytecodeViewer.viewer.showInferrable.isSelected()));
|
||||||
|
options.put("aexagg", String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()));
|
||||||
|
options.put("hideutf", String.valueOf(BytecodeViewer.viewer.hideUTF.isSelected()));
|
||||||
|
options.put("hidelongstrings", String.valueOf(BytecodeViewer.viewer.hideLongStrings.isSelected()));
|
||||||
|
options.put("commentmonitors", String.valueOf(BytecodeViewer.viewer.commentMonitor.isSelected()));
|
||||||
|
options.put("allowcorrecting", String.valueOf(BytecodeViewer.viewer.allowCorrecting.isSelected()));
|
||||||
|
options.put("labelledblocks", String.valueOf(BytecodeViewer.viewer.labelledBlocks.isSelected()));
|
||||||
|
options.put("j14classobj", String.valueOf(BytecodeViewer.viewer.j14ClassOBJ.isSelected()));
|
||||||
|
options.put("hidelangimports", String.valueOf(BytecodeViewer.viewer.hideLangImports.isSelected()));
|
||||||
|
options.put("recovertypehints", String.valueOf(BytecodeViewer.viewer.recoveryTypehInts.isSelected()));
|
||||||
|
options.put("forcereturningifs", String.valueOf(BytecodeViewer.viewer.forceTurningIFs.isSelected()));
|
||||||
|
options.put("forloopaggcapture", String.valueOf(BytecodeViewer.viewer.forLoopAGGCapture.isSelected()));
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue