Skip to content

Commit

Permalink
fix: use temp dir env var only in apps
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Oct 10, 2024
1 parent 063af8c commit c21cabc
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 112 deletions.
2 changes: 0 additions & 2 deletions jadx-cli/src/main/java/jadx/cli/JadxCLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import jadx.cli.plugins.JadxFilesGetter;
import jadx.commons.app.JadxCommonEnv;
import jadx.core.utils.exceptions.JadxArgsValidateException;
import jadx.core.utils.files.FileUtils;
import jadx.plugins.tools.JadxExternalPluginsLoader;

public class JadxCLI {
Expand All @@ -33,7 +32,6 @@ public static void main(String[] args) {
LOG.error("Process error:", e);
result = 1;
} finally {
FileUtils.deleteTempRootDir();
System.exit(result);
}
}
Expand Down
4 changes: 2 additions & 2 deletions jadx-cli/src/main/java/jadx/cli/plugins/JadxFilesGetter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import java.nio.file.Path;

import jadx.commons.app.JadxCommonFiles;
import jadx.commons.app.JadxTempFiles;
import jadx.core.plugins.files.IJadxFilesGetter;
import jadx.core.utils.files.FileUtils;

public class JadxFilesGetter implements IJadxFilesGetter {

Expand All @@ -22,7 +22,7 @@ public Path getCacheDir() {

@Override
public Path getTempDir() {
return FileUtils.getTempRootDir();
return JadxTempFiles.getTempRootDir();
}

private JadxFilesGetter() {
Expand Down
63 changes: 22 additions & 41 deletions jadx-cli/src/test/java/jadx/cli/TestInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jadx.core.utils.files.FileUtils;

import static org.assertj.core.api.Assertions.assertThat;

public class TestInput {
Expand All @@ -29,6 +27,9 @@ public class TestInput {
return true;
};

@TempDir
Path testDir;

@Test
public void testHelp() {
int result = JadxCLI.execute(new String[] { "--help" });
Expand All @@ -37,91 +38,76 @@ public void testHelp() {

@Test
public void testDexInput() throws Exception {
decompile("dex", "samples/hello.dex");
decompile("samples/hello.dex");
}

@Test
public void testSmaliInput() throws Exception {
decompile("smali", "samples/HelloWorld.smali");
decompile("samples/HelloWorld.smali");
}

@Test
public void testClassInput() throws Exception {
decompile("class", "samples/HelloWorld.class");
decompile("samples/HelloWorld.class");
}

@Test
public void testMultipleInput() throws Exception {
decompile("multi", "samples/hello.dex", "samples/HelloWorld.smali");
decompile("samples/hello.dex", "samples/HelloWorld.smali");
}

@Test
public void testFallbackMode() throws Exception {
Path tempDir = FileUtils.createTempDir("fallback");
List<String> args = buildArgs(tempDir, "samples/hello.dex");
args.add(0, "-f");

int result = JadxCLI.execute(args.toArray(new String[0]));
int result = JadxCLI.execute(buildArgs(List.of("-f"), "samples/hello.dex"));
assertThat(result).isEqualTo(0);
List<Path> files = collectJavaFilesInDir(tempDir);
List<Path> files = collectJavaFilesInDir(testDir);
assertThat(files).hasSize(1);
}

@Test
public void testSimpleMode() throws Exception {
Path tempDir = FileUtils.createTempDir("simple");
List<String> args = buildArgs(tempDir, "samples/hello.dex");
args.add(0, "--decompilation-mode");
args.add(1, "simple");

int result = JadxCLI.execute(args.toArray(new String[0]));
int result = JadxCLI.execute(buildArgs(List.of("--decompilation-mode", "simple"), "samples/hello.dex"));
assertThat(result).isEqualTo(0);
List<Path> files = collectJavaFilesInDir(tempDir);
List<Path> files = collectJavaFilesInDir(testDir);
assertThat(files).hasSize(1);
}

@Test
public void testResourceOnly() throws Exception {
Path tempDir = FileUtils.createTempDir("resourceOnly");
List<String> args = buildArgs(tempDir, "samples/resources-only.apk");

int result = JadxCLI.execute(args.toArray(new String[0]));
int result = JadxCLI.execute(buildArgs(List.of(), "samples/resources-only.apk"));
assertThat(result).isEqualTo(0);
List<Path> files = collectFilesInDir(tempDir,
List<Path> files = collectFilesInDir(testDir,
path -> path.getFileName().toString().equalsIgnoreCase("AndroidManifest.xml"));
assertThat(files).isNotEmpty();
}

private void decompile(String tmpDirName, String... inputSamples) throws URISyntaxException, IOException {
Path tempDir = FileUtils.createTempDir(tmpDirName);
List<String> args = buildArgs(tempDir, inputSamples);

int result = JadxCLI.execute(args.toArray(new String[0]));
private void decompile(String... inputSamples) throws URISyntaxException, IOException {
int result = JadxCLI.execute(buildArgs(List.of(), inputSamples));
assertThat(result).isEqualTo(0);
List<Path> resultJavaFiles = collectJavaFilesInDir(tempDir);
List<Path> resultJavaFiles = collectJavaFilesInDir(testDir);
assertThat(resultJavaFiles).isNotEmpty();

// do not copy input files as resources
for (Path path : collectFilesInDir(tempDir, LOG_ALL_FILES)) {
for (Path path : collectFilesInDir(testDir, LOG_ALL_FILES)) {
for (String inputSample : inputSamples) {
assertThat(path.toAbsolutePath().toString()).doesNotContain(inputSample);
}
}
}

private List<String> buildArgs(Path tempDir, String... inputSamples) throws URISyntaxException {
List<String> args = new ArrayList<>();
private String[] buildArgs(List<String> options, String... inputSamples) throws URISyntaxException {
List<String> args = new ArrayList<>(options);
args.add("-v");
args.add("-d");
args.add(tempDir.toAbsolutePath().toString());
args.add(testDir.toAbsolutePath().toString());

for (String inputSample : inputSamples) {
URL resource = getClass().getClassLoader().getResource(inputSample);
assertThat(resource).isNotNull();
String sampleFile = resource.toURI().getRawPath();
args.add(sampleFile);
}
return args;
return args.toArray(new String[0]);
}

private static List<Path> collectJavaFilesInDir(Path dir) throws IOException {
Expand All @@ -137,9 +123,4 @@ private static List<Path> collectFilesInDir(Path dir, PathMatcher matcher) throw
.collect(Collectors.toList());
}
}

@AfterAll
public static void cleanup() {
FileUtils.clearTempRootDir();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package jadx.commons.app;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class JadxTempFiles {
private static final String JADX_TMP_INSTANCE_PREFIX = "jadx-instance-";

private static final Path TEMP_ROOT_DIR = createTempRootDir();

public static Path getTempRootDir() {
return TEMP_ROOT_DIR;
}

private static Path createTempRootDir() {
try {
String jadxTmpDir = System.getenv("JADX_TMP_DIR");
Path dir;
if (jadxTmpDir != null) {
dir = Files.createTempDirectory(Paths.get(jadxTmpDir), JADX_TMP_INSTANCE_PREFIX);
} else {
dir = Files.createTempDirectory(JADX_TMP_INSTANCE_PREFIX);
}
dir.toFile().deleteOnExit();
return dir;
} catch (Exception e) {
throw new RuntimeException("Failed to create temp root directory", e);
}
}
}
2 changes: 2 additions & 0 deletions jadx-core/src/main/java/jadx/api/JadxDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public void load() {
reset();
JadxArgsValidator.validate(this);
LOG.info("loading ...");
FileUtils.updateTempRootDir(args.getFilesGetter().getTempDir());
loadPlugins();
loadInputFiles();

Expand Down Expand Up @@ -174,6 +175,7 @@ public void close() {
closeInputs();
closeLoaders();
args.close();
FileUtils.deleteTempRootDir();
}

private void closeInputs() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package jadx.core.plugins.files;

import java.nio.file.Files;
import java.nio.file.Path;

import jadx.core.utils.files.FileUtils;
Expand All @@ -8,22 +9,35 @@ public class TempFilesGetter implements IJadxFilesGetter {

public static final TempFilesGetter INSTANCE = new TempFilesGetter();

private final Path tempRootDir;

private TempFilesGetter() {
try {
tempRootDir = Files.createTempDirectory("jadx-temp-");
tempRootDir.toFile().deleteOnExit();
} catch (Exception e) {
throw new RuntimeException("Failed to create temp directory", e);
}
}

@Override
public Path getConfigDir() {
return FileUtils.getTempRootDir().resolve("config");
return makeSubDir("config");
}

@Override
public Path getCacheDir() {
return FileUtils.getTempRootDir().resolve("cache");
return makeSubDir("cache");
}

@Override
public Path getTempDir() {
return FileUtils.getTempRootDir().resolve("temp");
return tempRootDir;
}

private TempFilesGetter() {
// singleton
private Path makeSubDir(String subDir) {
Path dir = tempRootDir.resolve(subDir);
FileUtils.makeDirs(dir);
return dir;
}
}
57 changes: 27 additions & 30 deletions jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,31 @@ public class FileUtils {
public static final String JADX_TMP_INSTANCE_PREFIX = "jadx-instance-";
public static final String JADX_TMP_PREFIX = "jadx-tmp-";

private static Path tempRootDir = createTempRootDir();

private FileUtils() {
// utility class
}

public static synchronized Path updateTempRootDir(Path newTempRootDir) {
try {
Path dir = Files.createTempDirectory(newTempRootDir, JADX_TMP_INSTANCE_PREFIX);
tempRootDir = dir;
dir.toFile().deleteOnExit();
return dir;
} catch (Exception e) {
throw new JadxRuntimeException("Failed to update temp root directory", e);
}
}

private static Path createTempRootDir() {
try {
Path dir = Files.createTempDirectory(JADX_TMP_INSTANCE_PREFIX);
dir.toFile().deleteOnExit();
return dir;
} catch (Exception e) {
throw new JadxRuntimeException("Failed to create temp root directory", e);
}
}

public static List<Path> expandDirs(List<Path> paths) {
Expand Down Expand Up @@ -150,40 +174,13 @@ private static void deleteDir(Path dir) {
}
}

private static final Path TEMP_ROOT_DIR = createTempRootDir();

private static Path createTempRootDir() {
try {
String jadxTmpDir = System.getenv("JADX_TMP_DIR");
Path dir;
if (jadxTmpDir != null) {
dir = Files.createTempDirectory(Paths.get(jadxTmpDir), "jadx-instance-");
} else {
dir = Files.createTempDirectory(JADX_TMP_INSTANCE_PREFIX);
}
dir.toFile().deleteOnExit();
return dir;
} catch (Exception e) {
throw new JadxRuntimeException("Failed to create temp root directory", e);
}
}

public static Path getTempRootDir() {
return TEMP_ROOT_DIR;
}

public static void deleteTempRootDir() {
deleteDirIfExists(TEMP_ROOT_DIR);
}

public static void clearTempRootDir() {
deleteDirIfExists(TEMP_ROOT_DIR);
makeDirs(TEMP_ROOT_DIR);
deleteDirIfExists(tempRootDir);
}

public static Path createTempDir(String prefix) {
try {
Path dir = Files.createTempDirectory(TEMP_ROOT_DIR, prefix);
Path dir = Files.createTempDirectory(tempRootDir, prefix);
dir.toFile().deleteOnExit();
return dir;
} catch (Exception e) {
Expand All @@ -193,7 +190,7 @@ public static Path createTempDir(String prefix) {

public static Path createTempFile(String suffix) {
try {
Path path = Files.createTempFile(TEMP_ROOT_DIR, JADX_TMP_PREFIX, suffix);
Path path = Files.createTempFile(tempRootDir, JADX_TMP_PREFIX, suffix);
path.toFile().deleteOnExit();
return path;
} catch (Exception e) {
Expand Down
5 changes: 1 addition & 4 deletions jadx-core/src/main/java/jadx/core/utils/files/ZipFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.lang.reflect.UndeclaredThrowableException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -126,14 +125,12 @@ private static void moveBlockBack(RandomAccessFile file, long offset, long size,
}

private static File copyFile(File file) throws IOException {
var newFile = Files.createTempFile(file.getName(), ".apk").toFile();

var newFile = FileUtils.createTempFile(file.getName()).toFile();
try (var in = new FileInputStream(file)) {
try (var out = new FileOutputStream(newFile)) {
in.transferTo(out);
}
}

return newFile;
}

Expand Down
Loading

0 comments on commit c21cabc

Please sign in to comment.