mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-07 18:27:39 +02:00
Fix and correctly type ListRequirements.
This commit is contained in:
@@ -236,7 +236,7 @@ class CommandLine(object):
|
||||
# we expect the plugin to fail validation instead
|
||||
else:
|
||||
additional["nargs"] = requirement.max_elements
|
||||
additional["type"] = requirement.element_type.instance_type
|
||||
additional["type"] = requirement.element_type
|
||||
elif isinstance(requirement, volatility.framework.configuration.requirements.ChoiceRequirement):
|
||||
additional["type"] = str
|
||||
additional["choices"] = requirement.choices
|
||||
|
||||
@@ -63,44 +63,40 @@ class ListRequirement(interfaces_configuration.RequirementInterface):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
element_type: interfaces_configuration.InstanceRequirement,
|
||||
max_elements: int,
|
||||
min_elements: int, *args, **kwargs) -> None:
|
||||
element_type: typing.Type[interfaces_configuration.SimpleTypes] = str,
|
||||
max_elements: typing.Optional[int] = 0,
|
||||
min_elements: typing.Optional[int] = None, *args, **kwargs) -> None:
|
||||
"""Constructs the object
|
||||
|
||||
:param element_type: The (requirement) type of each element within the list
|
||||
:type element_type: interfaces_configuration.InstanceRequirement
|
||||
:param max_elements; The maximum number of acceptable elements this list can contain
|
||||
:type max_elements: int
|
||||
:param min_elements: The minimum number of acceptable elements this list can contain
|
||||
:type min_elements: int
|
||||
"""
|
||||
super().__init__(*args, **kwargs)
|
||||
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 # type: int
|
||||
self.max_elements = max_elements # type: int
|
||||
if not issubclass(element_type, interfaces_configuration.BasicTypes):
|
||||
raise TypeError("ListRequirements can only be populated with simple InstanceRequirements")
|
||||
self.element_type = element_type # type: typing.Type
|
||||
self.min_elements = min_elements or 0 # type: int
|
||||
self.max_elements = max_elements # type: typing.Optional[int]
|
||||
|
||||
def unsatisfied(self, context: interfaces.context.ContextInterface, config_path: str) -> typing.List[str]:
|
||||
"""Check the types on each of the returned values and their number and then call the element type's check for each one"""
|
||||
value = self.config_value(context, config_path)
|
||||
if value is None:
|
||||
raise ValueError("No value stored in the configuration")
|
||||
if not isinstance(value, list):
|
||||
# TODO: Check this is the correct response for an error
|
||||
raise ValueError("")
|
||||
if not (self.min_elements <= len(value) <= self.max_elements):
|
||||
vollog.log(constants.LOGLEVEL_V, "TypeError - List option provided more or less elements than allowed.")
|
||||
raise ValueError("Unexpected config value found: {}".format(repr(value)))
|
||||
if not (self.min_elements <= len(value)):
|
||||
vollog.log(constants.LOGLEVEL_V, "TypeError - Too few values provided to list option.")
|
||||
return [interfaces_configuration.path_join(config_path, self.name)]
|
||||
if not all([self._check_type(element, self.element_type.instance_type) for element in value]):
|
||||
if self.max_elements and not (len(value) < self.max_elements):
|
||||
vollog.log(constants.LOGLEVEL_V, "TypeError - Too many values provided to list option.")
|
||||
return [interfaces_configuration.path_join(config_path, self.name)]
|
||||
if not all([self._check_type(element, self.element_type) for element in value]):
|
||||
vollog.log(constants.LOGLEVEL_V, "TypeError - At least one element in the list is not of the correct type.")
|
||||
return [interfaces_configuration.path_join(config_path, self.name)]
|
||||
result = []
|
||||
for element in value:
|
||||
if isinstance(element, str):
|
||||
subresult = self.element_type.unsatisfied(context, element)
|
||||
for subvalue in subresult:
|
||||
result.append(subvalue)
|
||||
return result
|
||||
return []
|
||||
|
||||
|
||||
class ChoiceRequirement(interfaces_configuration.RequirementInterface):
|
||||
@@ -110,7 +106,6 @@ class ChoiceRequirement(interfaces_configuration.RequirementInterface):
|
||||
"""Constructs the object
|
||||
|
||||
:param choices: A list of possible string options that can be chosen from
|
||||
:type choices: list of str
|
||||
"""
|
||||
super().__init__(*args, **kwargs)
|
||||
if not isinstance(choices, list) or any([not isinstance(choice, str) for choice in choices]):
|
||||
|
||||
@@ -63,16 +63,13 @@ class AutomagicInterface(interfaces_configuration.ConfigurableInterface, metacla
|
||||
typing.Tuple[RequirementInterfaceType, ...]],
|
||||
shortcut: bool = True) \
|
||||
-> typing.List[typing.Tuple[str, str, interfaces_configuration.ConstructableRequirementInterface]]:
|
||||
"""Determines if there is actually an unfulfilled symbol requirement waiting
|
||||
"""Determines if there is actually an unfulfilled requirement waiting
|
||||
|
||||
This ensures we do not carry out an expensive search when there is no requirement for a particular symbol table.
|
||||
This ensures we do not carry out an expensive search when there is no requirement for a particular requirement
|
||||
|
||||
:param context: Context on which to operate
|
||||
:type context: ~volatility.framework.interfaces.context.ContextInterface
|
||||
:param config_path: Configuration path of the top-level requirement
|
||||
:type config_path: str
|
||||
:param requirement: Top-level requirement whose subrequirements will all be searched
|
||||
:type requirement: ~volatility.framework.interfaces.configuration.RequirementInterface
|
||||
:return: A list of tuples containing the config_path, sub_config_path and requirement identifying the SymbolRequirements
|
||||
"""
|
||||
sub_config_path = interfaces_configuration.path_join(config_path, requirement_root.name)
|
||||
|
||||
@@ -27,7 +27,9 @@ CONFIG_SEPARATOR = "."
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
ConfigSimpleType = typing.Union[str, int, float, bool, typing.List[typing.Union[str, int, float, bool]]]
|
||||
BasicTypes = (int, bool, bytes, str)
|
||||
SimpleTypes = typing.Union[int, bool, bytes, str]
|
||||
ConfigSimpleType = typing.Union[SimpleTypes, typing.List[SimpleTypes]]
|
||||
|
||||
|
||||
def path_join(*args) -> str:
|
||||
|
||||
Reference in New Issue
Block a user