GP-1895, GP-1894 Fix lib name case sensitivity comp during import, FSRL

Change RandomAccessFileByteProvider to auto specify a FSRL (if not
given).

Fix library name case comparisons to respect the loader's case
sensitivity.
This commit is contained in:
dev747368 2022-04-05 18:21:22 +00:00
parent fb054910e0
commit ab9664aa28
2 changed files with 30 additions and 6 deletions

View file

@ -18,6 +18,7 @@ package ghidra.app.util.bin;
import java.io.*; import java.io.*;
import ghidra.formats.gfilesystem.FSRL; import ghidra.formats.gfilesystem.FSRL;
import ghidra.formats.gfilesystem.FileSystemService;
import ghidra.util.Msg; import ghidra.util.Msg;
/** /**
@ -68,7 +69,7 @@ public class RandomAccessByteProvider implements ByteProvider {
* @throws IOException if the {@link File} does not exist or other error * @throws IOException if the {@link File} does not exist or other error
*/ */
public RandomAccessByteProvider(File file, String permissions) throws IOException { public RandomAccessByteProvider(File file, String permissions) throws IOException {
this(file, null, permissions); this(file, FileSystemService.getInstance().getLocalFSRL(file), permissions);
} }
private RandomAccessByteProvider(File file, FSRL fsrl, String permissions) throws IOException { private RandomAccessByteProvider(File file, FSRL fsrl, String permissions) throws IOException {

View file

@ -15,11 +15,12 @@
*/ */
package ghidra.app.util.opinion; package ghidra.app.util.opinion;
import java.io.File;
import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import ghidra.app.util.Option; import ghidra.app.util.Option;
@ -185,6 +186,12 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
return false; return false;
} }
protected Comparator<String> getLibNameComparator() {
return isCaseInsensitiveLibraryFilenames()
? String.CASE_INSENSITIVE_ORDER
: (s1, s2) -> s1.compareTo(s2);
}
/** /**
* Returns the path the loaded {@link ByteProvider} is located in. * Returns the path the loaded {@link ByteProvider} is located in.
* <p> * <p>
@ -340,6 +347,8 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
Program program = createProgram(provider, programName, imageBaseAddr, getName(), language, Program program = createProgram(provider, programName, imageBaseAddr, getName(), language,
compilerSpec, consumer); compilerSpec, consumer);
Comparator<String> libNameComparator = getLibNameComparator();
int transactionID = program.startTransaction("importing"); int transactionID = program.startTransaction("importing");
boolean success = false; boolean success = false;
try { try {
@ -351,9 +360,11 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
if (unprocessedLibraries != null) { if (unprocessedLibraries != null) {
ExternalManager extMgr = program.getExternalManager(); ExternalManager extMgr = program.getExternalManager();
String[] externalNames = extMgr.getExternalLibraryNames(); String[] externalNames = extMgr.getExternalLibraryNames();
Arrays.sort(externalNames); Arrays.sort(externalNames, libNameComparator);
for (String name : externalNames) { for (String name : externalNames) {
if (name.equals(provider.getName()) || Library.UNKNOWN.equals(name)) { if (libNameComparator.compare(name, provider.getName()) == 0 ||
libNameComparator.compare(name, program.getName()) == 0 ||
Library.UNKNOWN.equals(name)) {
// skip self-references and UNKNOWN library... // skip self-references and UNKNOWN library...
continue; continue;
} }
@ -457,7 +468,8 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
monitor.checkCanceled(); monitor.checkCanceled();
try { try {
String externalFileName = FilenameUtils.getName(externalLibName); String externalFileName = FilenameUtils.getName(externalLibName);
DomainObject matchingExtProgram = progsByName.get(externalFileName); DomainObject matchingExtProgram =
findLibraryWithCaseCorrectSearch(progsByName, externalFileName);
if (matchingExtProgram != null && matchingExtProgram.getDomainFile().exists()) { if (matchingExtProgram != null && matchingExtProgram.getDomainFile().exists()) {
extManager.setExternalPath(externalLibName, extManager.setExternalPath(externalLibName,
matchingExtProgram.getDomainFile().getPathname(), false); matchingExtProgram.getDomainFile().getPathname(), false);
@ -484,6 +496,17 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
} }
} }
protected Program findLibraryWithCaseCorrectSearch(Map<String, Program> progsByName,
String libName) {
Comparator<String> comparator = getLibNameComparator();
for (String s : progsByName.keySet()) {
if (comparator.compare(libName, s) == 0) {
return progsByName.get(s);
}
}
return null;
}
/** /**
* Find the libPathFilename within the specified importFolder. This method will handle * Find the libPathFilename within the specified importFolder. This method will handle
* relative path normalization. * relative path normalization.