Commit 699f7f67 authored by Skylot's avatar Skylot

fix: treat filesystem as case insensitive by default, option added for change

parent dae882d5
......@@ -76,6 +76,7 @@ options:
--deobf-rewrite-cfg - force to save deobfuscation map
--deobf-use-sourcename - use source file name as class name alias
--rename-flags - what to rename, comma-separated, 'case' for system case sensitivity, 'valid' for java identifiers, 'printable' characters, 'none' or 'all'
--fs-case-sensitive - treat filesystem as case sensitive, false by default
--cfg - save methods control flow graph to dot file
--raw-cfg - save methods control flow graph (use raw instructions)
-f, --fallback - make simple dump (using goto instead of 'if', 'for', etc)
......
package jadx.cli;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.core.utils.exceptions.JadxArgsValidateException;
import jadx.core.utils.files.FileUtils;
public class JadxCLI {
private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class);
......@@ -32,7 +27,6 @@ public class JadxCLI {
static int processAndSave(JadxCLIArgs inputArgs) {
JadxArgs args = inputArgs.toJadxArgs();
args.setFsCaseSensitive(getFsCaseSensitivity(args));
JadxDecompiler jadx = new JadxDecompiler(args);
try {
jadx.load();
......@@ -50,14 +44,4 @@ public class JadxCLI {
}
return errorsCount;
}
private static boolean getFsCaseSensitivity(JadxArgs args) {
List<File> testDirList = new ArrayList<>(3);
testDirList.add(args.getOutDir());
testDirList.add(args.getOutDirSrc());
if (!args.getInputFiles().isEmpty()) {
testDirList.add(args.getInputFiles().get(0));
}
return FileUtils.isCaseSensitiveFS(testDirList);
}
}
......@@ -85,6 +85,9 @@ public class JadxCLIArgs {
@Parameter(names = { "--deobf-use-sourcename" }, description = "use source file name as class name alias")
protected boolean deobfuscationUseSourceNameAsAlias = true;
@Parameter(names = { "--fs-case-sensitive" }, description = "treat filesystem as case sensitive, false by default")
protected boolean fsCaseSensitive = false;
@Parameter(names = { "--cfg" }, description = "save methods control flow graph to dot file")
protected boolean cfgOutput = false;
......@@ -190,6 +193,7 @@ public class JadxCLIArgs {
args.setRenameCaseSensitive(isRenameCaseSensitive());
args.setRenameValid(isRenameValid());
args.setRenamePrintable(isRenamePrintable());
args.setFsCaseSensitive(fsCaseSensitive);
return args;
}
......@@ -321,8 +325,11 @@ public class JadxCLIArgs {
}
}
static class RenameConverter implements IStringConverter<Set<RenameEnum>> {
public boolean isFsCaseSensitive() {
return fsCaseSensitive;
}
static class RenameConverter implements IStringConverter<Set<RenameEnum>> {
private final String paramName;
RenameConverter(String paramName) {
......
......@@ -13,13 +13,11 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.commons.io.IOCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
......@@ -188,52 +186,6 @@ public class FileUtils {
}
}
/**
* Checks dirs in order, fist success result returned
*/
public static boolean isCaseSensitiveFS(List<File> testDirList) {
for (File dir : testDirList) {
Optional<Boolean> result = isCaseSensitiveFSInternal(dir);
if (result.isPresent()) {
return result.get();
}
}
return IOCase.SYSTEM.isCaseSensitive();
}
public static boolean isCaseSensitiveFS(File testDir) {
Optional<Boolean> result = isCaseSensitiveFSInternal(testDir);
return result.orElseGet(IOCase.SYSTEM::isCaseSensitive);
}
private static Optional<Boolean> isCaseSensitiveFSInternal(@Nullable File testDir) {
if (testDir != null && testDir.exists() && testDir.isDirectory()) {
File caseCheckUpper = new File(testDir, "CaseCheck");
File caseCheckLow = new File(testDir, "casecheck");
try {
makeDirs(testDir);
if (caseCheckUpper.createNewFile()) {
boolean caseSensitive = !caseCheckLow.exists();
LOG.debug("Filesystem at {} is {}case-sensitive", testDir.getAbsolutePath(),
(caseSensitive ? "" : "NOT "));
return Optional.of(caseSensitive);
} else {
LOG.debug("Failed to create file: {}", caseCheckUpper.getAbsolutePath());
}
} catch (Exception e) {
LOG.debug("Failed to detect filesystem case-sensitivity by file creation", e);
} finally {
try {
Files.deleteIfExists(caseCheckUpper.toPath());
Files.deleteIfExists(caseCheckLow.toPath());
} catch (Exception e) {
// ignore
}
}
}
return Optional.empty();
}
public static File toFile(String path) {
if (path == null) {
return null;
......
......@@ -18,7 +18,6 @@ import jadx.api.JadxDecompiler;
import jadx.api.JavaClass;
import jadx.api.JavaPackage;
import jadx.api.ResourceFile;
import jadx.core.utils.files.FileUtils;
import jadx.gui.settings.JadxSettings;
public class JadxWrapper {
......@@ -37,8 +36,6 @@ public class JadxWrapper {
try {
JadxArgs jadxArgs = settings.toJadxArgs();
jadxArgs.setInputFile(file);
// output folder not known yet => use input dir as a best choice
jadxArgs.setFsCaseSensitive(FileUtils.isCaseSensitiveFS(file.getParentFile()));
this.decompiler = new JadxDecompiler(jadxArgs);
this.decompiler.load();
......
......@@ -281,6 +281,10 @@ public class JadxSettings extends JadxCLIArgs {
this.inlineAnonymousClasses = inlineAnonymousClasses;
}
public void setFsCaseSensitive(boolean fsCaseSensitive) {
this.fsCaseSensitive = fsCaseSensitive;
}
public boolean isAutoStartJobs() {
return autoStartJobs;
}
......
......@@ -353,6 +353,13 @@ public class JadxSettingsWindow extends JDialog {
needReload();
});
JCheckBox fsCaseSensitive = new JCheckBox();
fsCaseSensitive.setSelected(settings.isFsCaseSensitive());
fsCaseSensitive.addItemListener(e -> {
settings.setFsCaseSensitive(e.getStateChange() == ItemEvent.SELECTED);
needReload();
});
SettingsGroup other = new SettingsGroup(NLS.str("preferences.decompile"));
other.addRow(NLS.str("preferences.threads"), threadsCount);
other.addRow(NLS.str("preferences.excludedPackages"), NLS.str("preferences.excludedPackages.tooltip"),
......@@ -364,6 +371,7 @@ public class JadxSettingsWindow extends JDialog {
other.addRow(NLS.str("preferences.respectBytecodeAccessModifiers"), respectBytecodeAccessModifiers);
other.addRow(NLS.str("preferences.useImports"), useImports);
other.addRow(NLS.str("preferences.inlineAnonymous"), inlineAnonymous);
other.addRow(NLS.str("preferences.fsCaseSensitive"), fsCaseSensitive);
other.addRow(NLS.str("preferences.fallback"), fallback);
other.addRow(NLS.str("preferences.skipResourcesDecode"), resourceDecode);
return other;
......
......@@ -93,6 +93,7 @@ preferences.replaceConsts=Replace constants
preferences.respectBytecodeAccessModifiers=Respect bytecode access modifiers
preferences.useImports=Use import statements
preferences.inlineAnonymous=Inline anonymous classes
preferences.fsCaseSensitive=File system is case sensitive
preferences.skipResourcesDecode=Don't decode resources
preferences.autoSave=Auto save
preferences.threads=Processing threads count
......
......@@ -93,6 +93,7 @@ preferences.replaceConsts=Reemplazar constantes
#preferences.respectBytecodeAccessModifiers=
#preferences.useImports=
#preferences.inlineAnonymous=
#preferences.fsCaseSensitive=
preferences.skipResourcesDecode=No descodificar recursos
#preferences.autoSave=
preferences.threads=Número de hilos a procesar
......
......@@ -93,6 +93,7 @@ preferences.replaceConsts=替换常量
preferences.respectBytecodeAccessModifiers=遵守字节码访问修饰符
preferences.useImports=使用 import 语句
#preferences.inlineAnonymous=
#preferences.fsCaseSensitive=
preferences.skipResourcesDecode=不反编译资源文件
#preferences.autoSave=
preferences.threads=并行线程数
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment