From 269a68d84e63bbe49e31c21dbfbf17855bf588f8 Mon Sep 17 00:00:00 2001 From: Eric Hennenfent Date: Wed, 29 Jul 2020 18:30:50 -0700 Subject: [PATCH 1/2] Convert plugin list to dict --- manticore/core/manticore.py | 20 ++++++++++++-------- manticore/core/plugin.py | 6 +++++- manticore/ethereum/cli.py | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manticore/core/manticore.py b/manticore/core/manticore.py index f924008ce..f75ac0564 100644 --- a/manticore/core/manticore.py +++ b/manticore/core/manticore.py @@ -2,7 +2,7 @@ import itertools import logging import sys -import time +import typing import random import weakref from typing import Callable @@ -364,7 +364,7 @@ def __init__(self, initial_state, workspace_url=None, outputspace_url=None, **kw # the different type of events occur over an exploration. # Note that each callback will run in a worker process and that some # careful use of the shared context is needed. - self.plugins = set() + self.plugins = {} # Set initial root state if not isinstance(initial_state, StateBase): @@ -850,7 +850,7 @@ def generate_testcase(self, state, message: str = "test", name: str = "test") -> PickleSerializer().serialize(state, statef) # Let the plugins generate a state based report - for p in self.plugins: + for p in self.plugins.values(): p.generate_testcase(state, testcase, message) logger.info("Generated testcase No. %d - %s", testcase.num, message) @@ -860,11 +860,11 @@ def generate_testcase(self, state, message: str = "test", name: str = "test") -> def register_plugin(self, plugin: Plugin): # Global enumeration of valid events assert isinstance(plugin, Plugin) - assert plugin not in self.plugins, "Plugin instance already registered" + assert plugin.unique_name not in self.plugins, "Plugin instance already registered" assert getattr(plugin, "manticore", None) is None, "Plugin instance already owned" plugin.manticore = self - self.plugins.add(plugin) + self.plugins[plugin.unique_name] = plugin events = Eventful.all_events() prefix = Eventful.prefixes @@ -916,13 +916,17 @@ def register_plugin(self, plugin: Plugin): return plugin @at_not_running - def unregister_plugin(self, plugin): + def unregister_plugin(self, plugin: typing.Union[str, Plugin]): """ Removes a plugin from manticore. No events should be sent to it after """ - assert plugin in self.plugins, "Plugin instance not registered" + if type(plugin) is str: # Passed plugin.unique_name instead of value + assert plugin in self.plugins, "Plugin instance not registered" + plugin = self.plugins[plugin] + + assert plugin.unique_name in self.plugins, "Plugin instance not registered" plugin.on_unregister() - self.plugins.remove(plugin) + del self.plugins[plugin.unique_name] plugin.manticore = None def subscribe(self, name, callback): diff --git a/manticore/core/plugin.py b/manticore/core/plugin.py index 6d1a1c4b2..850369e37 100644 --- a/manticore/core/plugin.py +++ b/manticore/core/plugin.py @@ -55,9 +55,13 @@ def is_enabled(self): return context.get(self._enabled_key, True) @property - def name(self): + def name(self) -> str: return str(self.__class__) + @property + def unique_name(self) -> str: + return f"{self.name}_{id(self)}" + @contextmanager def locked_context(self, key=None, value_type=list): """ diff --git a/manticore/ethereum/cli.py b/manticore/ethereum/cli.py index 388fe7b30..fe90f870c 100644 --- a/manticore/ethereum/cli.py +++ b/manticore/ethereum/cli.py @@ -125,7 +125,7 @@ def ethereum_main(args, logger): m.register_plugin(filter_nohuman_constants) if m.plugins: - logger.info(f'Registered plugins: {", ".join(d.name for d in m.plugins)}') + logger.info(f'Registered plugins: {", ".join(d.name for d in m.plugins.values())}') logger.info("Beginning analysis") From 36eebc407147741c12cbd92fbdd873ed1753fc2f Mon Sep 17 00:00:00 2001 From: Eric Hennenfent Date: Wed, 5 Aug 2020 17:54:30 -0700 Subject: [PATCH 2/2] Appease MyPy --- manticore/core/manticore.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/manticore/core/manticore.py b/manticore/core/manticore.py index 2134d4f15..55785a6e0 100644 --- a/manticore/core/manticore.py +++ b/manticore/core/manticore.py @@ -364,7 +364,7 @@ def __init__(self, initial_state, workspace_url=None, outputspace_url=None, **kw # the different type of events occur over an exploration. # Note that each callback will run in a worker process and that some # careful use of the shared context is needed. - self.plugins = {} + self.plugins: typing.Dict[str, Plugin] = {} # Set initial root state if not isinstance(initial_state, StateBase): @@ -920,14 +920,16 @@ def unregister_plugin(self, plugin: typing.Union[str, Plugin]): """ Removes a plugin from manticore. No events should be sent to it after """ - if type(plugin) is str: # Passed plugin.unique_name instead of value + if isinstance(plugin, str): # Passed plugin.unique_name instead of value assert plugin in self.plugins, "Plugin instance not registered" - plugin = self.plugins[plugin] + plugin_inst: Plugin = self.plugins[plugin] + else: + plugin_inst = plugin - assert plugin.unique_name in self.plugins, "Plugin instance not registered" - plugin.on_unregister() - del self.plugins[plugin.unique_name] - plugin.manticore = None + assert plugin_inst.unique_name in self.plugins, "Plugin instance not registered" + plugin_inst.on_unregister() + del self.plugins[plugin_inst.unique_name] + plugin_inst.manticore = None def subscribe(self, name, callback): """ Register a callback to an event"""