mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Merge remote-tracking branch 'origin/GP-5208_dev747368_use_filename_compare_for_lookups--SQUASHED'
This commit is contained in:
commit
2c9f7fcacf
14 changed files with 155 additions and 71 deletions
|
@ -1181,27 +1181,20 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
|||
*/
|
||||
protected FSRL resolveLibraryFile(GFileSystem fs, Path libraryParentPath, String libraryName)
|
||||
throws IOException {
|
||||
GFile libraryParentDir = fs.lookup(
|
||||
libraryParentPath != null ? FilenameUtils.separatorsToUnix(libraryParentPath.toString())
|
||||
: null);
|
||||
boolean compareWithoutExtension = isOptionalLibraryFilenameExtensions() &&
|
||||
FilenameUtils.getExtension(libraryName).equals("");
|
||||
if (libraryParentDir != null) {
|
||||
Comparator<String> libNameComparator = getLibraryNameComparator();
|
||||
for (GFile file : fs.getListing(libraryParentDir)) {
|
||||
if (file.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
String compareName = file.getName();
|
||||
if (compareWithoutExtension) {
|
||||
compareName = FilenameUtils.getBaseName(compareName);
|
||||
}
|
||||
if (libNameComparator.compare(libraryName, compareName) == 0) {
|
||||
return file.getFSRL();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
String lpp = libraryParentPath != null
|
||||
? FilenameUtils.separatorsToUnix(libraryParentPath.toString())
|
||||
: null;
|
||||
String targetPath = FSUtilities.appendPath(lpp, libraryName);
|
||||
|
||||
Comparator<String> baseNameComp = getLibraryNameComparator();
|
||||
Comparator<String> nameComp = isOptionalLibraryFilenameExtensions() &&
|
||||
FilenameUtils.getExtension(libraryName).isEmpty()
|
||||
? (s1, s2) -> baseNameComp.compare(FilenameUtils.getBaseName(s1),
|
||||
FilenameUtils.getBaseName(s2))
|
||||
: baseNameComp;
|
||||
|
||||
GFile foundFile = fs.lookup(targetPath, nameComp);
|
||||
return foundFile != null && !foundFile.isDirectory() ? foundFile.getFSRL() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -66,6 +66,11 @@ public abstract class AbstractFileSystem<METADATATYPE> implements GFileSystem {
|
|||
return fsIndex.lookup(null, path, getFilenameComparator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndex.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile getRootDir() {
|
||||
return fsIndex.getRootDir();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.formats.gfilesystem;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
|
@ -23,6 +24,7 @@ import ghidra.app.util.bin.ByteProviderInputStream;
|
|||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileAttribute;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.classfinder.ExtensionPoint;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
@ -129,6 +131,26 @@ public interface GFileSystem extends Closeable, ExtensionPoint {
|
|||
*/
|
||||
GFile lookup(String path) throws IOException;
|
||||
|
||||
/**
|
||||
* Retrieves a {@link GFile} from this filesystem based on its full path and filename, using
|
||||
* the specified name comparison logic (eg. case sensitive vs insensitive).
|
||||
* <p>
|
||||
* @param path string path and filename of a file located in this filesystem. Use
|
||||
* {@code null} or "/" to retrieve the root directory
|
||||
* @param nameComp string comparator used to compare filenames. Use {@code null} to specify
|
||||
* the file system's native comparison logic.
|
||||
* @return {@link GFile} instance of requested file, null if not found.
|
||||
* @throws IOException if IO error when looking up file.
|
||||
*/
|
||||
default GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
// If you are seeing this error in your log file, it means your GFileSystem needs to be
|
||||
// updated to implement this lookup() method.
|
||||
Msg.error(GFileSystem.class,
|
||||
"Unimplemented %s.lookup(path, comparator), falling back to non-comparator lookup"
|
||||
.formatted(this.getClass().getSimpleName()));
|
||||
return lookup(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file system's root directory.
|
||||
* <p>
|
||||
|
|
|
@ -165,10 +165,14 @@ public abstract class GFileSystemBase implements GFileSystem {
|
|||
|
||||
@Override
|
||||
public GFile lookup(String path) throws IOException {
|
||||
return lookup(path, getFilenameComparator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
if (path == null || path.equals("/")) {
|
||||
return root;
|
||||
}
|
||||
Comparator<String> nameComp = getFilenameComparator();
|
||||
|
||||
GFile current = root;
|
||||
String[] parts = path.split("/");
|
||||
|
|
|
@ -213,7 +213,12 @@ public class LocalFileSystem implements GFileSystem, GFileHashProvider {
|
|||
|
||||
@Override
|
||||
public GFile lookup(String path) throws IOException {
|
||||
File f = lookupFile(null, path, null);
|
||||
return lookup(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
File f = lookupFile(null, path, nameComp);
|
||||
return f != null ? GFileImpl.fromPathString(this,
|
||||
FSUtilities.normalizeNativePath(f.getPath()), null, f.isDirectory(), f.length()) : null;
|
||||
}
|
||||
|
@ -327,24 +332,8 @@ public class LocalFileSystem implements GFileSystem, GFileHashProvider {
|
|||
// If not using a comparator, or if the requested path is a
|
||||
// root element (eg "/", or "c:\\"), don't do per-directory-path lookups.
|
||||
|
||||
if (OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS) {
|
||||
// On windows, getCanonicalFile() will return a corrected path using the case of
|
||||
// the file element on the file system (eg. "c:/users" -> "c:/Users"), if the
|
||||
// element exists.
|
||||
// We don't want to do this on unix-ish file systems as it will follow symlinks
|
||||
f = f.getCanonicalFile();
|
||||
}
|
||||
return FSUtilities.isSymlink(f) || f.exists() ? f : null;
|
||||
}
|
||||
|
||||
// Test the file's path using the name comparator
|
||||
if (f.exists() && baseDir == null) {
|
||||
// try to short-cut by comparing the entire path string
|
||||
File canonicalFile = f.getCanonicalFile();
|
||||
if (nameComp.compare(path,
|
||||
FSUtilities.normalizeNativePath((canonicalFile.getPath()))) == 0) {
|
||||
return canonicalFile;
|
||||
}
|
||||
f = updateCaseInsensitiveFilePath(f);
|
||||
return (FSUtilities.isSymlink(f) || f.exists()) ? f : null;
|
||||
}
|
||||
|
||||
// For path "/subdir/file", pathParts will contain, in reverse order:
|
||||
|
@ -375,7 +364,28 @@ public class LocalFileSystem implements GFileSystem, GFileHashProvider {
|
|||
}
|
||||
}
|
||||
|
||||
static File findInDir(File dir, String name, Comparator<String> nameComp) {
|
||||
static File updateCaseInsensitiveFilePath(File f) throws IOException {
|
||||
// On Windows, getCanonicalFile() will return a corrected path using the case of
|
||||
// the actual file element on the file system (eg. "c:/users" -> "c:/Users"), if the
|
||||
// element exists.
|
||||
return OperatingSystem.CURRENT_OPERATING_SYSTEM == OperatingSystem.WINDOWS
|
||||
? f.getCanonicalFile()
|
||||
: f;
|
||||
}
|
||||
|
||||
static File findInDir(File dir, String name, Comparator<String> nameComp) throws IOException {
|
||||
File exact = new File(dir, name);
|
||||
if (exact.exists()) {
|
||||
// Skip listing entire dir contents if exact match exists and the match agrees with
|
||||
// the caller's comparator. The comparator could reject this test, for example
|
||||
// if it was an exact case compare and the requested filename's case didn't match
|
||||
// the actual file's case (on windows).
|
||||
exact = updateCaseInsensitiveFilePath(exact);
|
||||
if (nameComp.compare(exact.getName(), name) == 0) {
|
||||
return exact;
|
||||
}
|
||||
}
|
||||
|
||||
// Searches for "name" in the list of files found in the directory.
|
||||
// Because a case-insensitive comparator could match on several files in the same directory,
|
||||
// query for all the files before picking a match: either an exact string match, or
|
||||
|
@ -393,7 +403,7 @@ public class LocalFileSystem implements GFileSystem, GFileHashProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(candidateMatches);
|
||||
Collections.sort(candidateMatches); // ensures stable results regardless if OS mutates order of listing on different runs
|
||||
return !candidateMatches.isEmpty() ? candidateMatches.get(0) : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
package ghidra.formats.gfilesystem;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||
|
@ -155,8 +154,13 @@ public class LocalFileSystemSub implements GFileSystem, GFileHashProvider {
|
|||
|
||||
@Override
|
||||
public GFile lookup(String path) throws IOException {
|
||||
File f = LocalFileSystem.lookupFile(localfsRootDir, path, null);
|
||||
if ( f == null ) {
|
||||
return lookup(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
File f = LocalFileSystem.lookupFile(localfsRootDir, path, nameComp);
|
||||
if (f == null) {
|
||||
return null;
|
||||
}
|
||||
GFile result = getGFile(f);
|
||||
|
|
|
@ -197,6 +197,11 @@ public class CartFileSystem implements GFileSystem {
|
|||
return fsIndexHelper.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndexHelper.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create byte provider for CaRT payload content that is
|
||||
* decompressed and decrypted.
|
||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.file.formats.complzss;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
|
@ -99,4 +100,9 @@ public class CompLzssFileSystem implements GFileSystem {
|
|||
return fsIndex.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndex.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -140,6 +140,11 @@ public class GZipFileSystem implements GFileSystem {
|
|||
return fsIndex.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndex.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteProvider getByteProvider(GFile file, TaskMonitor monitor)
|
||||
throws IOException, CancelledException {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.file.formats.ios.img2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
|
@ -106,4 +107,9 @@ public class Img2FileSystem implements GFileSystem {
|
|||
return fsIndexHelper.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndexHelper.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.file.formats.java;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
@ -134,6 +135,11 @@ public class JavaClassDecompilerFileSystem implements GFileSystem {
|
|||
return fsIndexHelper.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndexHelper.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteProvider getByteProvider(GFile file, TaskMonitor monitor)
|
||||
throws IOException, CancelledException {
|
||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.file.formats.lzfse;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
|
@ -111,4 +112,9 @@ public class LzfseFileSystem implements GFileSystem {
|
|||
public GFile lookup(String path) throws IOException {
|
||||
return fsIndex.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndex.lookup(null, path, nameComp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.file.formats.sparseimage;
|
|||
import static ghidra.formats.gfilesystem.fileinfo.FileAttributeType.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
|
@ -96,6 +97,11 @@ public class SparseImageFileSystem implements GFileSystem {
|
|||
return fsIndexHelper.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsIndexHelper.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
private ByteProvider getPayload(FSRL payloadFSRL, TaskMonitor monitor)
|
||||
throws CancelledException, IOException {
|
||||
return fsService.getDerivedByteProviderPush(byteProvider.getFSRL(), payloadFSRL, "sparse",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package skeleton;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
|
@ -112,6 +113,11 @@ public class SkeletonFileSystem implements GFileSystem {
|
|||
return fsih.lookup(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GFile lookup(String path, Comparator<String> nameComp) throws IOException {
|
||||
return fsih.lookup(null, path, nameComp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteProvider getByteProvider(GFile file, TaskMonitor monitor)
|
||||
throws IOException, CancelledException {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue