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: ...@@ -76,6 +76,7 @@ options:
--deobf-rewrite-cfg - force to save deobfuscation map --deobf-rewrite-cfg - force to save deobfuscation map
--deobf-use-sourcename - use source file name as class name alias --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' --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 --cfg - save methods control flow graph to dot file
--raw-cfg - save methods control flow graph (use raw instructions) --raw-cfg - save methods control flow graph (use raw instructions)
-f, --fallback - make simple dump (using goto instead of 'if', 'for', etc) -f, --fallback - make simple dump (using goto instead of 'if', 'for', etc)
......
package jadx.cli; package jadx.cli;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jadx.api.JadxArgs; import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler; import jadx.api.JadxDecompiler;
import jadx.core.utils.exceptions.JadxArgsValidateException; import jadx.core.utils.exceptions.JadxArgsValidateException;
import jadx.core.utils.files.FileUtils;
public class JadxCLI { public class JadxCLI {
private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class);
...@@ -32,7 +27,6 @@ public class JadxCLI { ...@@ -32,7 +27,6 @@ public class JadxCLI {
static int processAndSave(JadxCLIArgs inputArgs) { static int processAndSave(JadxCLIArgs inputArgs) {
JadxArgs args = inputArgs.toJadxArgs(); JadxArgs args = inputArgs.toJadxArgs();
args.setFsCaseSensitive(getFsCaseSensitivity(args));
JadxDecompiler jadx = new JadxDecompiler(args); JadxDecompiler jadx = new JadxDecompiler(args);
try { try {
jadx.load(); jadx.load();
...@@ -50,14 +44,4 @@ public class JadxCLI { ...@@ -50,14 +44,4 @@ public class JadxCLI {
} }
return errorsCount; 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 { ...@@ -85,6 +85,9 @@ public class JadxCLIArgs {
@Parameter(names = { "--deobf-use-sourcename" }, description = "use source file name as class name alias") @Parameter(names = { "--deobf-use-sourcename" }, description = "use source file name as class name alias")
protected boolean deobfuscationUseSourceNameAsAlias = true; 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") @Parameter(names = { "--cfg" }, description = "save methods control flow graph to dot file")
protected boolean cfgOutput = false; protected boolean cfgOutput = false;
...@@ -190,6 +193,7 @@ public class JadxCLIArgs { ...@@ -190,6 +193,7 @@ public class JadxCLIArgs {
args.setRenameCaseSensitive(isRenameCaseSensitive()); args.setRenameCaseSensitive(isRenameCaseSensitive());
args.setRenameValid(isRenameValid()); args.setRenameValid(isRenameValid());
args.setRenamePrintable(isRenamePrintable()); args.setRenamePrintable(isRenamePrintable());
args.setFsCaseSensitive(fsCaseSensitive);
return args; return args;
} }
...@@ -321,8 +325,11 @@ public class JadxCLIArgs { ...@@ -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; private final String paramName;
RenameConverter(String paramName) { RenameConverter(String paramName) {
......
...@@ -13,13 +13,11 @@ import java.util.ArrayList; ...@@ -13,13 +13,11 @@ import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import org.apache.commons.io.IOCase;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -188,52 +186,6 @@ public class FileUtils { ...@@ -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) { public static File toFile(String path) {
if (path == null) { if (path == null) {
return null; return null;
......
...@@ -18,7 +18,6 @@ import jadx.api.JadxDecompiler; ...@@ -18,7 +18,6 @@ import jadx.api.JadxDecompiler;
import jadx.api.JavaClass; import jadx.api.JavaClass;
import jadx.api.JavaPackage; import jadx.api.JavaPackage;
import jadx.api.ResourceFile; import jadx.api.ResourceFile;
import jadx.core.utils.files.FileUtils;
import jadx.gui.settings.JadxSettings; import jadx.gui.settings.JadxSettings;
public class JadxWrapper { public class JadxWrapper {
...@@ -37,8 +36,6 @@ public class JadxWrapper { ...@@ -37,8 +36,6 @@ public class JadxWrapper {
try { try {
JadxArgs jadxArgs = settings.toJadxArgs(); JadxArgs jadxArgs = settings.toJadxArgs();
jadxArgs.setInputFile(file); 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 = new JadxDecompiler(jadxArgs);
this.decompiler.load(); this.decompiler.load();
......
...@@ -281,6 +281,10 @@ public class JadxSettings extends JadxCLIArgs { ...@@ -281,6 +281,10 @@ public class JadxSettings extends JadxCLIArgs {
this.inlineAnonymousClasses = inlineAnonymousClasses; this.inlineAnonymousClasses = inlineAnonymousClasses;
} }
public void setFsCaseSensitive(boolean fsCaseSensitive) {
this.fsCaseSensitive = fsCaseSensitive;
}
public boolean isAutoStartJobs() { public boolean isAutoStartJobs() {
return autoStartJobs; return autoStartJobs;
} }
......
...@@ -353,6 +353,13 @@ public class JadxSettingsWindow extends JDialog { ...@@ -353,6 +353,13 @@ public class JadxSettingsWindow extends JDialog {
needReload(); 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")); SettingsGroup other = new SettingsGroup(NLS.str("preferences.decompile"));
other.addRow(NLS.str("preferences.threads"), threadsCount); other.addRow(NLS.str("preferences.threads"), threadsCount);
other.addRow(NLS.str("preferences.excludedPackages"), NLS.str("preferences.excludedPackages.tooltip"), other.addRow(NLS.str("preferences.excludedPackages"), NLS.str("preferences.excludedPackages.tooltip"),
...@@ -364,6 +371,7 @@ public class JadxSettingsWindow extends JDialog { ...@@ -364,6 +371,7 @@ public class JadxSettingsWindow extends JDialog {
other.addRow(NLS.str("preferences.respectBytecodeAccessModifiers"), respectBytecodeAccessModifiers); other.addRow(NLS.str("preferences.respectBytecodeAccessModifiers"), respectBytecodeAccessModifiers);
other.addRow(NLS.str("preferences.useImports"), useImports); other.addRow(NLS.str("preferences.useImports"), useImports);
other.addRow(NLS.str("preferences.inlineAnonymous"), inlineAnonymous); 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.fallback"), fallback);
other.addRow(NLS.str("preferences.skipResourcesDecode"), resourceDecode); other.addRow(NLS.str("preferences.skipResourcesDecode"), resourceDecode);
return other; return other;
......
...@@ -93,6 +93,7 @@ preferences.replaceConsts=Replace constants ...@@ -93,6 +93,7 @@ preferences.replaceConsts=Replace constants
preferences.respectBytecodeAccessModifiers=Respect bytecode access modifiers preferences.respectBytecodeAccessModifiers=Respect bytecode access modifiers
preferences.useImports=Use import statements preferences.useImports=Use import statements
preferences.inlineAnonymous=Inline anonymous classes preferences.inlineAnonymous=Inline anonymous classes
preferences.fsCaseSensitive=File system is case sensitive
preferences.skipResourcesDecode=Don't decode resources preferences.skipResourcesDecode=Don't decode resources
preferences.autoSave=Auto save preferences.autoSave=Auto save
preferences.threads=Processing threads count preferences.threads=Processing threads count
......
...@@ -93,6 +93,7 @@ preferences.replaceConsts=Reemplazar constantes ...@@ -93,6 +93,7 @@ preferences.replaceConsts=Reemplazar constantes
#preferences.respectBytecodeAccessModifiers= #preferences.respectBytecodeAccessModifiers=
#preferences.useImports= #preferences.useImports=
#preferences.inlineAnonymous= #preferences.inlineAnonymous=
#preferences.fsCaseSensitive=
preferences.skipResourcesDecode=No descodificar recursos preferences.skipResourcesDecode=No descodificar recursos
#preferences.autoSave= #preferences.autoSave=
preferences.threads=Número de hilos a procesar preferences.threads=Número de hilos a procesar
......
...@@ -93,6 +93,7 @@ preferences.replaceConsts=替换常量 ...@@ -93,6 +93,7 @@ preferences.replaceConsts=替换常量
preferences.respectBytecodeAccessModifiers=遵守字节码访问修饰符 preferences.respectBytecodeAccessModifiers=遵守字节码访问修饰符
preferences.useImports=使用 import 语句 preferences.useImports=使用 import 语句
#preferences.inlineAnonymous= #preferences.inlineAnonymous=
#preferences.fsCaseSensitive=
preferences.skipResourcesDecode=不反编译资源文件 preferences.skipResourcesDecode=不反编译资源文件
#preferences.autoSave= #preferences.autoSave=
preferences.threads=并行线程数 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