fix: treat filesystem as case insensitive by default, option added for change
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
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=并行线程数
|
||||
|
||||
Reference in New Issue
Block a user