From 7b252d8b73f999ff14d77df904d33497a323cd21 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Sun, 8 Jan 2017 02:04:55 +0000 Subject: [PATCH] Refactor InstanceRequriement into the interfaces file. This also fixes a minor bug where a property was used in the initializer, which can't be read before initialization. --- .../framework/configuration/requirements.py | 36 ++++--------------- volatility/framework/interfaces/automagic.py | 2 +- .../framework/interfaces/configuration.py | 26 +++++++++++++- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/volatility/framework/configuration/requirements.py b/volatility/framework/configuration/requirements.py index 030c7d0b9..e3cd10848 100644 --- a/volatility/framework/configuration/requirements.py +++ b/volatility/framework/configuration/requirements.py @@ -28,45 +28,23 @@ class MultiRequirement(interfaces_configuration.RequirementInterface): return self.validate_children(context, config_path) -class InstanceRequirement(interfaces_configuration.RequirementInterface): - """Class to represent a single simple type (such as a boolean, a string, an integer or a series of bytes)""" - instance_type = bool - - def add_requirement(self, requirement): - """Always raises a TypeError as instance requirements cannot have children""" - raise TypeError("Instance Requirements cannot have subrequirements") - - def remove_requirement(self, requirement): - """Always raises a TypeError as instance requirements cannot have children""" - raise TypeError("Instance Requirements cannot have subrequirements") - - def validate(self, context, config_path): - """Validates the instance requirement based upon its `instance_type`.""" - value = self.config_value(context, config_path, None) - if not isinstance(value, self.instance_type): - vollog.log(constants.LOGLEVEL_V, - "TypeError - {} requirements only accept {} type: {}".format(self.name, - self.instance_type.__name__, - value)) - return False - return True +class BooleanRequirement(interfaces_configuration.InstanceRequirement): + """A requirement type that contains a boolean value""" + # Note, this must be a separate class in order to differentiate between Booleans and other instance requirements -BooleanRequirement = InstanceRequirement - - -class IntRequirement(InstanceRequirement): +class IntRequirement(interfaces_configuration.InstanceRequirement): """A requirement type that contains a single integer""" instance_type = int -class StringRequirement(InstanceRequirement): +class StringRequirement(interfaces_configuration.InstanceRequirement): """A requirement type that contains a single unicode string""" # TODO: Maybe add string length limits? instance_type = str -class BytesRequirement(InstanceRequirement): +class BytesRequirement(interfaces_configuration.InstanceRequirement): """A requirement type that contains a byte string""" instance_type = bytes @@ -115,7 +93,7 @@ class ListRequirement(interfaces_configuration.RequirementInterface): :type min_elements: int """ super().__init__(*args, **kwargs) - if not isinstance(element_type, InstanceRequirement): + if not isinstance(element_type, interfaces_configuration.InstanceRequirement): raise TypeError("ListRequirements can only contain simple InstanceRequirements") self.element_type = element_type self.min_elements = min_elements diff --git a/volatility/framework/interfaces/automagic.py b/volatility/framework/interfaces/automagic.py index 0ee46b0be..fadcbb613 100644 --- a/volatility/framework/interfaces/automagic.py +++ b/volatility/framework/interfaces/automagic.py @@ -37,7 +37,7 @@ class AutomagicInterface(interfaces_configuration.ConfigurableInterface, metacla def __init__(self, context, config_path, *args, **kwargs): super().__init__(context, config_path) for requirement in self.get_requirements(): - if not isinstance(requirement, (requirements.InstanceRequirement, + if not isinstance(requirement, (interfaces_configuration.InstanceRequirement, requirements.ChoiceRequirement, requirements.ListRequirement)): raise ValueError( diff --git a/volatility/framework/interfaces/configuration.py b/volatility/framework/interfaces/configuration.py index cb10e113b..fda0cb7ee 100644 --- a/volatility/framework/interfaces/configuration.py +++ b/volatility/framework/interfaces/configuration.py @@ -277,6 +277,30 @@ class RequirementInterface(validity.ValidityRoutines, metaclass = ABCMeta): """ +class InstanceRequirement(RequirementInterface): + """Class to represent a single simple type (such as a boolean, a string, an integer or a series of bytes)""" + instance_type = bool + + def add_requirement(self, requirement): + """Always raises a TypeError as instance requirements cannot have children""" + raise TypeError("Instance Requirements cannot have subrequirements") + + def remove_requirement(self, requirement): + """Always raises a TypeError as instance requirements cannot have children""" + raise TypeError("Instance Requirements cannot have subrequirements") + + def validate(self, context, config_path): + """Validates the instance requirement based upon its `instance_type`.""" + value = self.config_value(context, config_path, None) + if not isinstance(value, self.instance_type): + vollog.log(constants.LOGLEVEL_V, + "TypeError - {} requirements only accept {} type: {}".format(self.name, + self.instance_type.__name__, + value)) + return False + return True + + class ClassRequirement(RequirementInterface): """Requires a specific class. This is used as means to serialize specific classes for :class:`TranslationLayerRequirement` and :class:`SymbolRequirement` classes.""" @@ -378,7 +402,7 @@ class ConfigurableInterface(validity.ValidityRoutines, metaclass = ABCMeta): for requirement in self.get_requirements(): # Create the (private) properties using the config as backend storage # TODO: Based on the requirement, do proper type checking - setattr(self, "_" + requirement.name, self.config.get(requirement.name, requirement.default)) + setattr(self, "_" + requirement.name, self._context._config.get(requirement.name, requirement.default)) @property def context(self):