feat: plugin options, add verify checksum option for dex input (#1385)

This commit is contained in:
Skylot
2022-02-21 19:13:03 +00:00
parent 09335395f5
commit 54683e3198
24 changed files with 435 additions and 25 deletions
@@ -16,6 +16,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.plugins.input.JadxInputPlugin;
import jadx.api.plugins.options.JadxPluginOptions;
import jadx.api.plugins.options.OptionDescription;
public class JadxPluginManager {
private static final Logger LOG = LoggerFactory.getLogger(JadxPluginManager.class);
@@ -56,9 +58,34 @@ public class JadxPluginManager {
if (!allPlugins.add(pluginData)) {
throw new IllegalArgumentException("Duplicate plugin id: " + pluginData + ", class " + plugin.getClass());
}
if (plugin instanceof JadxPluginOptions) {
verifyOptions(((JadxPluginOptions) plugin), pluginData.getPluginId());
}
return pluginData;
}
private void verifyOptions(JadxPluginOptions plugin, String pluginId) {
List<OptionDescription> descriptions = plugin.getOptionsDescriptions();
if (descriptions == null) {
throw new IllegalArgumentException("Null option descriptions in plugin id: " + pluginId);
}
String prefix = pluginId + '.';
descriptions.forEach(descObj -> {
String optName = descObj.name();
if (optName == null || !optName.startsWith(prefix)) {
throw new IllegalArgumentException("Plugin option name should start with plugin id: '" + prefix + "', option: " + optName);
}
String desc = descObj.description();
if (desc == null || desc.isEmpty()) {
throw new IllegalArgumentException("Plugin option description not set, plugin: " + pluginId);
}
List<String> values = descObj.values();
if (values == null) {
throw new IllegalArgumentException("Plugin option values is null, option: " + optName + ", plugin: " + pluginId);
}
});
}
public boolean unload(String pluginId) {
boolean result = allPlugins.removeIf(pd -> {
String id = pd.getPluginId();
@@ -87,6 +114,13 @@ public class JadxPluginManager {
.collect(Collectors.toList());
}
public List<JadxPluginOptions> getPluginsWithOptions() {
return resolvedPlugins.stream()
.filter(JadxPluginOptions.class::isInstance)
.map(JadxPluginOptions.class::cast)
.collect(Collectors.toList());
}
private synchronized void resolve() {
Map<String, List<PluginData>> provides = allPlugins.stream()
.collect(Collectors.groupingBy(p -> p.getInfo().getProvides()));
@@ -0,0 +1,13 @@
package jadx.api.plugins.options;
import java.util.List;
import java.util.Map;
import jadx.api.plugins.JadxPlugin;
public interface JadxPluginOptions extends JadxPlugin {
void setOptions(Map<String, String> options);
List<OptionDescription> getOptionsDescriptions();
}
@@ -0,0 +1,25 @@
package jadx.api.plugins.options;
import java.util.List;
import org.jetbrains.annotations.Nullable;
public interface OptionDescription {
String name();
String description();
/**
* Possible values.
* Empty if not a limited set
*/
List<String> values();
/**
* Default value.
* Null if required
*/
@Nullable
String defaultValue();
}
@@ -0,0 +1,47 @@
package jadx.api.plugins.options.impl;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import jadx.api.plugins.options.OptionDescription;
public class JadxOptionDescription implements OptionDescription {
private final String name;
private final String desc;
private final String defaultValue;
private final List<String> values;
public JadxOptionDescription(String name, String desc, @Nullable String defaultValue, List<String> values) {
this.name = name;
this.desc = desc;
this.defaultValue = defaultValue;
this.values = values;
}
@Override
public String name() {
return name;
}
@Override
public String description() {
return desc;
}
@Override
public @Nullable String defaultValue() {
return defaultValue;
}
@Override
public List<String> values() {
return values;
}
@Override
public String toString() {
return "OptionDescription{" + desc + ", values=" + values + '}';
}
}