feat(plugins): allow to load classes using input stream or byte array in jadx-input plugin (#1457)
This commit is contained in:
+10
-2
@@ -19,8 +19,8 @@ import org.slf4j.LoggerFactory;
|
||||
import jadx.api.plugins.utils.CommonFileUtils;
|
||||
import jadx.api.plugins.utils.ZipSecurity;
|
||||
|
||||
public class JavaFileLoader {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JavaFileLoader.class);
|
||||
public class JavaInputLoader {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JavaInputLoader.class);
|
||||
|
||||
private static final int MAX_MAGIC_SIZE = 4;
|
||||
private static final byte[] JAVA_CLASS_FILE_MAGIC = { (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE };
|
||||
@@ -37,6 +37,14 @@ public class JavaFileLoader {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<JavaClassReader> loadInputStream(InputStream in, String name) throws IOException {
|
||||
return loadReader(in, name, null, null);
|
||||
}
|
||||
|
||||
public JavaClassReader loadClass(byte[] content, String fileName) {
|
||||
return new JavaClassReader(getNextUniqId(), fileName, content);
|
||||
}
|
||||
|
||||
private List<JavaClassReader> loadFromFile(File file) {
|
||||
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
|
||||
return loadReader(inputStream, file.getName(), file, null);
|
||||
+46
-1
@@ -1,8 +1,11 @@
|
||||
package jadx.plugins.input.java;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -10,6 +13,7 @@ import jadx.api.plugins.JadxPluginInfo;
|
||||
import jadx.api.plugins.input.JadxInputPlugin;
|
||||
import jadx.api.plugins.input.data.ILoadResult;
|
||||
import jadx.api.plugins.input.data.impl.EmptyLoadResult;
|
||||
import jadx.plugins.input.java.utils.JavaClassParseException;
|
||||
|
||||
public class JavaInputPlugin implements JadxInputPlugin {
|
||||
|
||||
@@ -29,10 +33,51 @@ public class JavaInputPlugin implements JadxInputPlugin {
|
||||
}
|
||||
|
||||
public static ILoadResult loadClassFiles(List<Path> inputFiles, @Nullable Closeable closeable) {
|
||||
List<JavaClassReader> readers = new JavaFileLoader().collectFiles(inputFiles);
|
||||
List<JavaClassReader> readers = new JavaInputLoader().collectFiles(inputFiles);
|
||||
if (readers.isEmpty()) {
|
||||
return EmptyLoadResult.INSTANCE;
|
||||
}
|
||||
return new JavaLoadResult(readers, closeable);
|
||||
}
|
||||
|
||||
public static ILoadResult loadClassFiles(List<Path> inputFiles) {
|
||||
return loadClassFiles(inputFiles, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for provide several inputs by using load methods from {@link JavaInputLoader} class.
|
||||
*/
|
||||
public static ILoadResult load(Function<JavaInputLoader, List<JavaClassReader>> loader) {
|
||||
return wrapClassReaders(loader.apply(new JavaInputLoader()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient method for load class file or jar from input stream.
|
||||
* Should be used only once per JadxDecompiler instance.
|
||||
* For load several times use {@link JavaInputPlugin#load(Function)} method.
|
||||
*/
|
||||
public static ILoadResult loadFromInputStream(InputStream in, String fileName) {
|
||||
try {
|
||||
return wrapClassReaders(new JavaInputLoader().loadInputStream(in, fileName));
|
||||
} catch (Exception e) {
|
||||
throw new JavaClassParseException("Failed to read input stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient method for load single class file by content.
|
||||
* Should be used only once per JadxDecompiler instance.
|
||||
* For load several times use {@link JavaInputPlugin#load(Function)} method.
|
||||
*/
|
||||
public static ILoadResult loadSingleClass(byte[] content, String fileName) {
|
||||
JavaClassReader reader = new JavaInputLoader().loadClass(content, fileName);
|
||||
return new JavaLoadResult(Collections.singletonList(reader));
|
||||
}
|
||||
|
||||
public static ILoadResult wrapClassReaders(List<JavaClassReader> readers) {
|
||||
if (readers.isEmpty()) {
|
||||
return EmptyLoadResult.INSTANCE;
|
||||
}
|
||||
return new JavaLoadResult(readers);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -20,6 +20,10 @@ public class JavaLoadResult implements ILoadResult {
|
||||
@Nullable
|
||||
private final Closeable closeable;
|
||||
|
||||
public JavaLoadResult(List<JavaClassReader> readers) {
|
||||
this(readers, null);
|
||||
}
|
||||
|
||||
public JavaLoadResult(List<JavaClassReader> readers, @Nullable Closeable closeable) {
|
||||
this.readers = readers;
|
||||
this.closeable = closeable;
|
||||
@@ -47,7 +51,6 @@ public class JavaLoadResult implements ILoadResult {
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
readers.clear();
|
||||
if (closeable != null) {
|
||||
closeable.close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user