mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-7298: The ProgramLoader and ImportBatchTask now properly validate
loader options
This commit is contained in:
@@ -1665,16 +1665,7 @@ public class HeadlessAnalyzer {
|
||||
return true;
|
||||
}
|
||||
catch (LoadException e) {
|
||||
Msg.error(this, "The ProgramLoader could not successfully load " + fsrl +
|
||||
" with the provided import parameters. Please ensure that any specified" +
|
||||
" processor/cspec arguments are compatible with the loader that is used during" +
|
||||
" import and try again.");
|
||||
if (options.loaderClass != null && options.loaderClass != BinaryLoader.class) {
|
||||
Msg.error(this,
|
||||
"NOTE: Import failure may be due to missing opinion for \"" +
|
||||
options.loaderClass.getSimpleName() +
|
||||
"\". If so, please contact Ghidra team for assistance.");
|
||||
}
|
||||
Msg.error(this, "REPORT: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -629,8 +629,9 @@ public class ProgramLoader {
|
||||
LoadSpec loadSpec = loadSpecChooser.choose(loaderMap);
|
||||
if (loadSpec == null) {
|
||||
String name = Objects.requireNonNullElse(p.getName(), "???");
|
||||
Msg.info(ProgramLoader.class, "No load spec found for import file: " + name);
|
||||
throw new LoadException("No load spec found");
|
||||
throw new LoadException(
|
||||
"No load spec found. Loader/processor/cspec not compatible with import file: " +
|
||||
name);
|
||||
}
|
||||
return loadSpec;
|
||||
}
|
||||
@@ -642,12 +643,12 @@ public class ProgramLoader {
|
||||
* @param loadSpec The {@link LoadSpec}
|
||||
* @return The {@link Loader} {@link Option}s, with any loader arguments applied
|
||||
* @throws LanguageNotFoundException if there was a problem getting the language
|
||||
* @throws LoadException if the {@link Loader} had {@code null} options
|
||||
* @throws LoadException if the {@link Loader} had {@code null} or invalid options
|
||||
*/
|
||||
private List<Option> getLoaderOptions(ByteProvider p, LoadSpec loadSpec)
|
||||
throws LanguageNotFoundException, LoadException {
|
||||
List<Option> options =
|
||||
loadSpec.getLoader().getDefaultOptions(p, loadSpec, null, false, mirror);
|
||||
Loader loader = loadSpec.getLoader();
|
||||
List<Option> options = loader.getDefaultOptions(p, loadSpec, null, false, mirror);
|
||||
if (options == null) {
|
||||
throw new LoadException("Cannot load with null options");
|
||||
}
|
||||
@@ -673,15 +674,14 @@ public class ProgramLoader {
|
||||
if (option.getArg() != null && arg.equalsIgnoreCase(option.getArg())) {
|
||||
Object oldVal = option.getValue();
|
||||
if (option.parseAndSetValueByType(val, addrFactory)) {
|
||||
Msg.info(ProgramLoader.class, String.format(
|
||||
"Successfully applied \"%s\" to \"%s\" (old: \"%s\", new: \"%s\")",
|
||||
arg, option.getName(), oldVal, val));
|
||||
Msg.info(ProgramLoader.class,
|
||||
"Applied \"%s\" to \"%s\" (old: \"%s\", new: \"%s\")".formatted(arg,
|
||||
option.getName(), oldVal, val));
|
||||
}
|
||||
else {
|
||||
Msg.error(ProgramLoader.class, String.format(
|
||||
"Failed to apply \"%s\" to \"%s\" (old: \"%s\", bad: \"%s\")", arg,
|
||||
option.getName(), oldVal, val));
|
||||
return null;
|
||||
throw new LoadException(
|
||||
"Failed to apply \"%s\" to \"%s\" (old: \"%s\", bad: \"%s\")"
|
||||
.formatted(arg, option.getName(), oldVal, val));
|
||||
}
|
||||
foundIt = true;
|
||||
break;
|
||||
@@ -691,6 +691,13 @@ public class ProgramLoader {
|
||||
Msg.warn(ProgramLoader.class, "Skipping unsupported " + arg + " argument");
|
||||
}
|
||||
}
|
||||
|
||||
String error = loader.validateOptions(p, loadSpec, options, null);
|
||||
if (error != null) {
|
||||
throw new LoadException("Options are not valid for %s: %s"
|
||||
.formatted(loader.getClass().getSimpleName(), error));
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public interface Loader extends ExtensionPoint, Comparable<Loader> {
|
||||
SystemUtilities.getBooleanProperty("disable.loader.logging", false);
|
||||
|
||||
/**
|
||||
* A {@link Loader} configuration
|
||||
* Generic settings acquired from the importer, used to configure the load.
|
||||
*
|
||||
* @param provider The bytes to load.
|
||||
* @param importName The name for the primary {@link Loaded} {@link DomainObject}. Path
|
||||
@@ -79,7 +79,7 @@ public interface Loader extends ExtensionPoint, Comparable<Loader> {
|
||||
* @param mirrorFsLayout True if the filesystem layout should be mirrored when
|
||||
* {@link LoadResults#save(TaskMonitor) saving}; otherwise, false
|
||||
* @param loadSpec The {@link LoadSpec} to use during load.
|
||||
* @param options The load options.
|
||||
* @param options Loader-specific options (could be null).
|
||||
* @param consumer A reference to the object "consuming" the returned {@link LoadResults}, used
|
||||
* to ensure the underlying {@link Program}s are only closed when every consumer is done
|
||||
* with it (see {@link LoadResults#close()}).
|
||||
|
||||
@@ -146,10 +146,19 @@ public class ImportBatchTask extends Task {
|
||||
try {
|
||||
MessageLog messageLog = new MessageLog();
|
||||
Project project = AppInfo.getActiveProject();
|
||||
List<Option> options = getOptionsFor(batchLoadConfig, loadSpec, byteProvider);
|
||||
if (options != null) {
|
||||
Loader loader = batchLoadConfig.getLoader();
|
||||
String error = loader.validateOptions(byteProvider, loadSpec, options, null);
|
||||
if (error != null) {
|
||||
Msg.error(this, "Options are not valid for %s: %s"
|
||||
.formatted(loader.getClass().getSimpleName(), error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
ImporterSettings settings = new ImporterSettings(byteProvider,
|
||||
fixupProjectFilename(destInfo.second), project, destInfo.first.getPathname(),
|
||||
mirrorFs, loadSpec, getOptionsFor(batchLoadConfig, loadSpec, byteProvider),
|
||||
this, messageLog, monitor);
|
||||
mirrorFs, loadSpec, options, this, messageLog, monitor);
|
||||
try (LoadResults<? extends DomainObject> loadResults =
|
||||
loadSpec.getLoader().load(settings)) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user