Fix pattern equivalence doc style for consistency
parent
f9e9c50db9
commit
b55c3bb1df
|
@ -30,7 +30,8 @@ def _get_pattern_canonicalizer():
|
|||
"""
|
||||
Get a canonicalization transformer for STIX patterns.
|
||||
|
||||
:return: The transformer
|
||||
Returns:
|
||||
The transformer
|
||||
"""
|
||||
|
||||
# The transformers are either stateless or contain no state which changes
|
||||
|
@ -64,11 +65,14 @@ def equivalent_patterns(pattern1, pattern2, stix_version=stix2.DEFAULT_VERSION):
|
|||
"""
|
||||
Determine whether two STIX patterns are semantically equivalent.
|
||||
|
||||
:param pattern1: The first STIX pattern
|
||||
:param pattern2: The second STIX pattern
|
||||
:param stix_version: The STIX version to use for pattern parsing, as a
|
||||
string ("2.0", "2.1", etc). Defaults to library-wide default version.
|
||||
:return: True if the patterns are semantically equivalent; False if not
|
||||
Args:
|
||||
pattern1: The first STIX pattern
|
||||
pattern2: The second STIX pattern
|
||||
stix_version: The STIX version to use for pattern parsing, as a string
|
||||
("2.0", "2.1", etc). Defaults to library-wide default version.
|
||||
|
||||
Returns:
|
||||
True if the patterns are semantically equivalent; False if not
|
||||
"""
|
||||
patt_ast1 = stix2.pattern_visitor.create_pattern_object(
|
||||
pattern1, version=stix_version,
|
||||
|
@ -96,12 +100,14 @@ def find_equivalent_patterns(
|
|||
on an input iterable and is implemented as a generator of matches. So you
|
||||
can "stream" patterns in and matching patterns will be streamed out.
|
||||
|
||||
:param search_pattern: A search pattern as a string
|
||||
:param patterns: An iterable over patterns as strings
|
||||
:param stix_version: The STIX version to use for pattern parsing, as a
|
||||
string ("2.0", "2.1", etc). Defaults to library-wide default version.
|
||||
:return: A generator iterator producing the semantically equivalent
|
||||
patterns
|
||||
Args:
|
||||
search_pattern: A search pattern as a string
|
||||
patterns: An iterable over patterns as strings
|
||||
stix_version: The STIX version to use for pattern parsing, as a string
|
||||
("2.0", "2.1", etc). Defaults to library-wide default version.
|
||||
|
||||
Returns:
|
||||
A generator iterator producing the semantically equivalent patterns
|
||||
"""
|
||||
search_pattern_ast = stix2.pattern_visitor.create_pattern_object(
|
||||
search_pattern, version=stix_version,
|
||||
|
|
|
@ -16,9 +16,12 @@ def generic_cmp(value1, value2):
|
|||
Generic comparator of values which uses the builtin '<' and '>' operators.
|
||||
Assumes the values can be compared that way.
|
||||
|
||||
:param value1: The first value
|
||||
:param value2: The second value
|
||||
:return: -1, 0, or 1 depending on whether value1 is less, equal, or greater
|
||||
Args:
|
||||
value1: The first value
|
||||
value2: The second value
|
||||
|
||||
Returns:
|
||||
-1, 0, or 1 depending on whether value1 is less, equal, or greater
|
||||
than value2
|
||||
"""
|
||||
|
||||
|
@ -30,12 +33,15 @@ def iter_lex_cmp(seq1, seq2, cmp):
|
|||
Generic lexicographical compare function, which works on two iterables and
|
||||
a comparator function.
|
||||
|
||||
:param seq1: The first iterable
|
||||
:param seq2: The second iterable
|
||||
:param cmp: a two-arg callable comparator for values iterated over. It
|
||||
must behave analogously to this function, returning <0, 0, or >0 to
|
||||
express the ordering of the two values.
|
||||
:return: <0 if seq1 < seq2; >0 if seq1 > seq2; 0 if they're equal
|
||||
Args:
|
||||
seq1: The first iterable
|
||||
seq2: The second iterable
|
||||
cmp: a two-arg callable comparator for values iterated over. It
|
||||
must behave analogously to this function, returning <0, 0, or >0 to
|
||||
express the ordering of the two values.
|
||||
|
||||
Returns:
|
||||
<0 if seq1 < seq2; >0 if seq1 > seq2; 0 if they're equal
|
||||
"""
|
||||
|
||||
it1 = iter(seq1)
|
||||
|
@ -84,11 +90,14 @@ def iter_in(value, seq, cmp):
|
|||
a comparator function. This function checks whether the given value is
|
||||
contained in the given iterable.
|
||||
|
||||
:param value: A value
|
||||
:param seq: An iterable
|
||||
:param cmp: A 2-arg comparator function which must return 0 if the args
|
||||
are equal
|
||||
:return: True if the value is found in the iterable, False if it is not
|
||||
Args:
|
||||
value: A value
|
||||
seq: An iterable
|
||||
cmp: A 2-arg comparator function which must return 0 if the args
|
||||
are equal
|
||||
|
||||
Returns:
|
||||
True if the value is found in the iterable, False if it is not
|
||||
"""
|
||||
result = False
|
||||
for seq_val in seq:
|
||||
|
|
|
@ -32,9 +32,12 @@ def generic_constant_cmp(const1, const2):
|
|||
Generic comparator for most _Constant instances. They must have a "value"
|
||||
attribute whose value supports the builtin comparison operators.
|
||||
|
||||
:param const1: The first _Constant instance
|
||||
:param const2: The second _Constant instance
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
const1: The first _Constant instance
|
||||
const2: The second _Constant instance
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
return generic_cmp(const1.value, const2.value)
|
||||
|
@ -44,9 +47,12 @@ def bool_cmp(value1, value2):
|
|||
"""
|
||||
Compare two boolean constants.
|
||||
|
||||
:param value1: The first BooleanConstant instance
|
||||
:param value2: The second BooleanConstant instance
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
value1: The first BooleanConstant instance
|
||||
value2: The second BooleanConstant instance
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
|
||||
|
@ -72,9 +78,12 @@ def hex_cmp(value1, value2):
|
|||
Compare two STIX "hex" values. This decodes to bytes and compares that.
|
||||
It does *not* do a string compare on the hex representations.
|
||||
|
||||
:param value1: The first HexConstant
|
||||
:param value2: The second HexConstant
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
value1: The first HexConstant
|
||||
value2: The second HexConstant
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
bytes1 = bytes.fromhex(value1.value)
|
||||
|
@ -88,9 +97,12 @@ def bin_cmp(value1, value2):
|
|||
Compare two STIX "binary" values. This decodes to bytes and compares that.
|
||||
It does *not* do a string compare on the base64 representations.
|
||||
|
||||
:param value1: The first BinaryConstant
|
||||
:param value2: The second BinaryConstant
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
value1: The first BinaryConstant
|
||||
value2: The second BinaryConstant
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
bytes1 = base64.standard_b64decode(value1.value)
|
||||
|
@ -103,9 +115,12 @@ def list_cmp(value1, value2):
|
|||
"""
|
||||
Compare lists order-insensitively.
|
||||
|
||||
:param value1: The first ListConstant
|
||||
:param value2: The second ListConstant
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
value1: The first ListConstant
|
||||
value2: The second ListConstant
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
|
||||
|
@ -144,9 +159,12 @@ def object_path_component_cmp(comp1, comp2):
|
|||
Ints and strings compare as usual to each other; ints compare less than
|
||||
strings.
|
||||
|
||||
:param comp1: An object path component (string or int)
|
||||
:param comp2: An object path component (string or int)
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
comp1: An object path component (string or int)
|
||||
comp2: An object path component (string or int)
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
|
||||
|
@ -172,8 +190,11 @@ def object_path_to_raw_values(path):
|
|||
properties; "*" index steps become that string; and numeric index steps
|
||||
become integers.
|
||||
|
||||
:param path: An ObjectPath instance
|
||||
:return: A generator iterator over the values
|
||||
Args:
|
||||
path: An ObjectPath instance
|
||||
|
||||
Returns:
|
||||
A generator iterator over the values
|
||||
"""
|
||||
|
||||
for comp in path.property_path:
|
||||
|
@ -195,9 +216,12 @@ def object_path_cmp(path1, path2):
|
|||
"""
|
||||
Compare two object paths.
|
||||
|
||||
:param path1: The first ObjectPath instance
|
||||
:param path2: The second ObjectPath instance
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
path1: The first ObjectPath instance
|
||||
path2: The second ObjectPath instance
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
if path1.object_type_name < path2.object_type_name:
|
||||
|
@ -224,9 +248,12 @@ def comparison_operator_cmp(op1, op2):
|
|||
"""
|
||||
Compare two comparison operators.
|
||||
|
||||
:param op1: The first comparison operator (a string)
|
||||
:param op2: The second comparison operator (a string)
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
op1: The first comparison operator (a string)
|
||||
op2: The second comparison operator (a string)
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
op1_idx = _COMPARISON_OP_ORDER.index(op1)
|
||||
|
@ -241,9 +268,12 @@ def constant_cmp(value1, value2):
|
|||
"""
|
||||
Compare two constants.
|
||||
|
||||
:param value1: The first _Constant instance
|
||||
:param value2: The second _Constant instance
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
value1: The first _Constant instance
|
||||
value2: The second _Constant instance
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
|
||||
|
@ -284,9 +314,12 @@ def simple_comparison_expression_cmp(expr1, expr2):
|
|||
Compare "simple" comparison expressions: those which aren't AND/OR
|
||||
combinations, just <path> <op> <value> comparisons.
|
||||
|
||||
:param expr1: first _ComparisonExpression instance
|
||||
:param expr2: second _ComparisonExpression instance
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
expr1: first _ComparisonExpression instance
|
||||
expr2: second _ComparisonExpression instance
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
|
||||
|
@ -315,9 +348,12 @@ def comparison_expression_cmp(expr1, expr2):
|
|||
expressions' sub-components. To achieve an order-insensitive comparison,
|
||||
the ASTs must be canonically ordered first.
|
||||
|
||||
:param expr1: The first comparison expression
|
||||
:param expr2: The second comparison expression
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
expr1: The first comparison expression
|
||||
expr2: The second comparison expression
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
if isinstance(expr1, _ComparisonExpression) \
|
||||
|
|
|
@ -64,9 +64,12 @@ def observation_expression_cmp(expr1, expr2):
|
|||
the expressions' sub-components. To achieve an order-insensitive
|
||||
comparison, the ASTs must be canonically ordered first.
|
||||
|
||||
:param expr1: The first observation expression
|
||||
:param expr2: The second observation expression
|
||||
:return: <0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
Args:
|
||||
expr1: The first observation expression
|
||||
expr2: The second observation expression
|
||||
|
||||
Returns:
|
||||
<0, 0, or >0 depending on whether the first arg is less, equal or
|
||||
greater than the second
|
||||
"""
|
||||
type1 = type(expr1)
|
||||
|
|
|
@ -22,13 +22,17 @@ def _dupe_ast(ast):
|
|||
"""
|
||||
Create a duplicate of the given AST.
|
||||
|
||||
Note: the comparison expression "leaves", i.e. simple <path> <op> <value>
|
||||
comparisons are currently not duplicated. I don't think it's necessary as
|
||||
of this writing; they are never changed. But revisit this if/when
|
||||
necessary.
|
||||
Note:
|
||||
The comparison expression "leaves", i.e. simple <path> <op> <value>
|
||||
comparisons are currently not duplicated. I don't think it's necessary
|
||||
as of this writing; they are never changed. But revisit this if/when
|
||||
necessary.
|
||||
|
||||
:param ast: The AST to duplicate
|
||||
:return: The duplicate AST
|
||||
Args:
|
||||
ast: The AST to duplicate
|
||||
|
||||
Returns:
|
||||
The duplicate AST
|
||||
"""
|
||||
if isinstance(ast, AndBooleanExpression):
|
||||
result = AndBooleanExpression([
|
||||
|
@ -108,8 +112,11 @@ class ComparisonExpressionTransformer(Transformer):
|
|||
Invoke a transformer callback method based on the given ast root node
|
||||
type.
|
||||
|
||||
:param ast: The AST
|
||||
:return: The callback's result
|
||||
Args:
|
||||
ast: The AST
|
||||
|
||||
Returns:
|
||||
The callback's result
|
||||
"""
|
||||
|
||||
if isinstance(ast, AndBooleanExpression):
|
||||
|
@ -153,8 +160,11 @@ class OrderDedupeTransformer(
|
|||
"""
|
||||
Sort/dedupe children. AND and OR can be treated identically.
|
||||
|
||||
:param ast: The comparison expression AST
|
||||
:return: The same AST node, but with sorted children
|
||||
Args:
|
||||
ast: The comparison expression AST
|
||||
|
||||
Returns:
|
||||
The same AST node, but with sorted children
|
||||
"""
|
||||
sorted_children = sorted(
|
||||
ast.operands, key=functools.cmp_to_key(comparison_expression_cmp),
|
||||
|
@ -201,8 +211,11 @@ class FlattenTransformer(ComparisonExpressionTransformer):
|
|||
little difference is that we can absorb AND children if we're an AND
|
||||
ourselves; and OR for OR.
|
||||
|
||||
:param ast: The comparison expression AST
|
||||
:return: The same AST node, but with flattened children
|
||||
Args:
|
||||
ast: The comparison expression AST
|
||||
|
||||
Returns:
|
||||
The same AST node, but with flattened children
|
||||
"""
|
||||
|
||||
changed = False
|
||||
|
|
|
@ -38,8 +38,11 @@ def _dupe_ast(ast):
|
|||
observation expressions are currently not duplicated. I don't think it's
|
||||
necessary as of this writing. But revisit this if/when necessary.
|
||||
|
||||
:param ast: The AST to duplicate
|
||||
:return: The duplicate AST
|
||||
Args:
|
||||
ast: The AST to duplicate
|
||||
|
||||
Returns:
|
||||
The duplicate AST
|
||||
"""
|
||||
if isinstance(ast, AndObservationExpression):
|
||||
result = AndObservationExpression([
|
||||
|
@ -160,8 +163,11 @@ class ObservationExpressionTransformer(Transformer):
|
|||
Invoke a transformer callback method based on the given ast root node
|
||||
type.
|
||||
|
||||
:param ast: The AST
|
||||
:return: The callback's result
|
||||
Args:
|
||||
ast: The AST
|
||||
|
||||
Returns:
|
||||
The callback's result
|
||||
"""
|
||||
|
||||
dispatch_name = self._DISPATCH_NAME_MAP.get(type(ast))
|
||||
|
@ -292,10 +298,12 @@ class AbsorptionTransformer(
|
|||
the right does not "contain" the left. You would need two A's on the
|
||||
right.
|
||||
|
||||
:param exprs_containee: The expressions we want to check for containment
|
||||
:param exprs_container: The expressions acting as the "container"
|
||||
:return: True if the containee is contained in the container; False if
|
||||
not
|
||||
Args:
|
||||
exprs_containee: The expressions we want to check for containment
|
||||
exprs_container: The expressions acting as the "container"
|
||||
|
||||
Returns:
|
||||
True if the containee is contained in the container; False if not
|
||||
"""
|
||||
|
||||
# make our own list we are free to manipulate without affecting the
|
||||
|
@ -336,10 +344,12 @@ class AbsorptionTransformer(
|
|||
in the container (rhs), B follows A, so it "contains" the lhs even
|
||||
though there is other stuff mixed in.
|
||||
|
||||
:param exprs_containee: The expressions we want to check for containment
|
||||
:param exprs_container: The expressions acting as the "container"
|
||||
:return: True if the containee is contained in the container; False if
|
||||
not
|
||||
Args:
|
||||
exprs_containee: The expressions we want to check for containment
|
||||
exprs_container: The expressions acting as the "container"
|
||||
|
||||
Returns:
|
||||
True if the containee is contained in the container; False if not
|
||||
"""
|
||||
|
||||
ee_iter = iter(exprs_containee)
|
||||
|
|
|
@ -25,9 +25,12 @@ def _path_is(object_path, path_pattern):
|
|||
index path step; _ANY_KEY matches any key path step, and _ANY matches any
|
||||
path step.
|
||||
|
||||
:param object_path: An ObjectPath instance
|
||||
:param path_pattern: An iterable giving the pattern path steps
|
||||
:return: True if the path matches the pattern; False if not
|
||||
Args:
|
||||
object_path: An ObjectPath instance
|
||||
path_pattern: An iterable giving the pattern path steps
|
||||
|
||||
Returns:
|
||||
True if the path matches the pattern; False if not
|
||||
"""
|
||||
path_values = object_path_to_raw_values(object_path)
|
||||
|
||||
|
@ -70,8 +73,9 @@ def _mask_bytes(ip_bytes, prefix_size):
|
|||
Retain the high-order 'prefix_size' bits from ip_bytes, and zero out the
|
||||
remaining low-order bits. This side-effects ip_bytes.
|
||||
|
||||
:param ip_bytes: A mutable byte sequence (e.g. a bytearray)
|
||||
:param prefix_size: An integer prefix size
|
||||
Args:
|
||||
ip_bytes: A mutable byte sequence (e.g. a bytearray)
|
||||
prefix_size: An integer prefix size
|
||||
"""
|
||||
addr_size_bytes = len(ip_bytes)
|
||||
addr_size_bits = 8 * addr_size_bytes
|
||||
|
@ -99,8 +103,9 @@ def windows_reg_key(comp_expr):
|
|||
being compared. This enables case-insensitive comparisons between two
|
||||
patterns, for those values. This side-effects the given AST.
|
||||
|
||||
:param comp_expr: A _ComparisonExpression object whose type is
|
||||
windows-registry-key
|
||||
Args:
|
||||
comp_expr: A _ComparisonExpression object whose type is
|
||||
windows-registry-key
|
||||
"""
|
||||
if _path_is(comp_expr.lhs, ("key",)) \
|
||||
or _path_is(comp_expr.lhs, ("values", _ANY_IDX, "name")):
|
||||
|
@ -119,7 +124,8 @@ def ipv4_addr(comp_expr):
|
|||
|
||||
This side-effects the given AST.
|
||||
|
||||
:param comp_expr: A _ComparisonExpression object whose type is ipv4-addr.
|
||||
Args:
|
||||
comp_expr: A _ComparisonExpression object whose type is ipv4-addr.
|
||||
"""
|
||||
if _path_is(comp_expr.lhs, ("value",)):
|
||||
value = comp_expr.rhs.value
|
||||
|
@ -179,7 +185,8 @@ def ipv6_addr(comp_expr):
|
|||
|
||||
This side-effects the given AST.
|
||||
|
||||
:param comp_expr: A _ComparisonExpression object whose type is ipv6-addr.
|
||||
Args:
|
||||
comp_expr: A _ComparisonExpression object whose type is ipv6-addr.
|
||||
"""
|
||||
if _path_is(comp_expr.lhs, ("value",)):
|
||||
value = comp_expr.rhs.value
|
||||
|
|
Loading…
Reference in New Issue