Merge branch 'master' of github.com:oasis-open/cti-python-stix2 into main
commit
52d806b349
|
@ -0,0 +1,5 @@
|
|||
comparison
|
||||
==============
|
||||
|
||||
.. automodule:: stix2.equivalence.patterns.compare.comparison
|
||||
:members:
|
|
@ -0,0 +1,5 @@
|
|||
observation
|
||||
==============
|
||||
|
||||
.. automodule:: stix2.equivalence.patterns.compare.observation
|
||||
:members:
|
|
@ -0,0 +1,5 @@
|
|||
comparison
|
||||
==============
|
||||
|
||||
.. automodule:: stix2.equivalence.patterns.transform.comparison
|
||||
:members:
|
|
@ -0,0 +1,5 @@
|
|||
observation
|
||||
==============
|
||||
|
||||
.. automodule:: stix2.equivalence.patterns.transform.observation
|
||||
:members:
|
|
@ -0,0 +1,5 @@
|
|||
specials
|
||||
==============
|
||||
|
||||
.. automodule:: stix2.equivalence.patterns.transform.specials
|
||||
:members:
|
|
@ -0,0 +1,5 @@
|
|||
patterns
|
||||
==============
|
||||
|
||||
.. automodule:: stix2.equivalence.patterns
|
||||
:members:
|
|
@ -0,0 +1,5 @@
|
|||
equivalence
|
||||
==============
|
||||
|
||||
.. automodule:: stix2.equivalence
|
||||
:members:
|
|
@ -6,6 +6,7 @@
|
|||
confidence
|
||||
datastore
|
||||
environment
|
||||
equivalence
|
||||
exceptions
|
||||
markings
|
||||
parsing
|
||||
|
|
|
@ -210,7 +210,7 @@ class TAXIICollectionSource(DataSource):
|
|||
|
||||
if len(stix_obj):
|
||||
stix_obj = parse(stix_obj[0], allow_custom=self.allow_custom, version=version)
|
||||
if stix_obj.id != stix_id:
|
||||
if stix_obj['id'] != stix_id:
|
||||
# check - was added to handle erroneous TAXII servers
|
||||
stix_obj = None
|
||||
else:
|
||||
|
@ -246,7 +246,7 @@ class TAXIICollectionSource(DataSource):
|
|||
all_data = [parse(stix_obj, allow_custom=self.allow_custom, version=version) for stix_obj in all_data]
|
||||
|
||||
# check - was added to handle erroneous TAXII servers
|
||||
all_data_clean = [stix_obj for stix_obj in all_data if stix_obj.id == stix_id]
|
||||
all_data_clean = [stix_obj for stix_obj in all_data if stix_obj['id'] == stix_id]
|
||||
|
||||
return all_data_clean
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
"""Python APIs for STIX 2 Semantic Equivalence.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: equivalence
|
||||
|
||||
patterns
|
||||
|
||||
|
|
||||
"""
|
|
@ -1,3 +1,14 @@
|
|||
"""Python APIs for STIX 2 Pattern Semantic Equivalence.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: patterns
|
||||
|
||||
compare
|
||||
transform
|
||||
|
||||
|
|
||||
"""
|
||||
|
||||
import stix2
|
||||
from stix2.equivalence.patterns.compare.observation import (
|
||||
observation_expression_cmp,
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
"""
|
||||
Some generic comparison utility functions.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: compare
|
||||
|
||||
comparison
|
||||
observation
|
||||
|
||||
|
|
||||
"""
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
"""
|
||||
Generic AST transformation classes.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: transform
|
||||
|
||||
comparison
|
||||
observation
|
||||
specials
|
||||
|
||||
|
|
||||
"""
|
||||
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ def make_constant(value):
|
|||
return value
|
||||
|
||||
try:
|
||||
return parse_into_datetime(value)
|
||||
return TimestampConstant(value)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
|
@ -366,7 +366,7 @@ class _ComparisonExpression(_PatternExpression):
|
|||
else:
|
||||
self.rhs = make_constant(rhs)
|
||||
self.negated = negated
|
||||
self.root_type = self.lhs.object_type_name
|
||||
self.root_types = {self.lhs.object_type_name}
|
||||
|
||||
def __str__(self):
|
||||
if self.negated:
|
||||
|
@ -506,15 +506,17 @@ class _BooleanExpression(_PatternExpression):
|
|||
"""
|
||||
def __init__(self, operator, operands):
|
||||
self.operator = operator
|
||||
self.operands = []
|
||||
self.operands = list(operands)
|
||||
for arg in operands:
|
||||
if not hasattr(self, "root_type"):
|
||||
self.root_type = arg.root_type
|
||||
elif self.root_type and (self.root_type != arg.root_type) and operator == "AND":
|
||||
raise ValueError("All operands to an 'AND' expression must have the same object type")
|
||||
elif self.root_type and (self.root_type != arg.root_type):
|
||||
self.root_type = None
|
||||
self.operands.append(arg)
|
||||
if not hasattr(self, "root_types"):
|
||||
self.root_types = arg.root_types
|
||||
elif operator == "AND":
|
||||
self.root_types &= arg.root_types
|
||||
else:
|
||||
self.root_types |= arg.root_types
|
||||
|
||||
if not self.root_types:
|
||||
raise ValueError("All operands to an 'AND' expression must be satisfiable with the same object type")
|
||||
|
||||
def __str__(self):
|
||||
sub_exprs = []
|
||||
|
@ -613,8 +615,8 @@ class ParentheticalExpression(_PatternExpression):
|
|||
"""
|
||||
def __init__(self, exp):
|
||||
self.expression = exp
|
||||
if hasattr(exp, "root_type"):
|
||||
self.root_type = exp.root_type
|
||||
if hasattr(exp, "root_types"):
|
||||
self.root_types = exp.root_types
|
||||
|
||||
def __str__(self):
|
||||
return "(%s)" % self.expression
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import datetime
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
import stix2
|
||||
from stix2.pattern_visitor import create_pattern_object
|
||||
import stix2.utils
|
||||
|
||||
|
||||
def test_create_comparison_expression():
|
||||
|
@ -482,6 +484,44 @@ def test_invalid_startstop_qualifier():
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input_, expected_class, expected_value", [
|
||||
(1, stix2.patterns.IntegerConstant, 1),
|
||||
(1.5, stix2.patterns.FloatConstant, 1.5),
|
||||
("abc", stix2.patterns.StringConstant, "abc"),
|
||||
(True, stix2.patterns.BooleanConstant, True),
|
||||
(
|
||||
"2001-02-10T21:36:15Z", stix2.patterns.TimestampConstant,
|
||||
stix2.utils.STIXdatetime(2001, 2, 10, 21, 36, 15, tzinfo=pytz.utc),
|
||||
),
|
||||
(
|
||||
datetime.datetime(2001, 2, 10, 21, 36, 15, tzinfo=pytz.utc),
|
||||
stix2.patterns.TimestampConstant,
|
||||
stix2.utils.STIXdatetime(2001, 2, 10, 21, 36, 15, tzinfo=pytz.utc),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_make_constant_simple(input_, expected_class, expected_value):
|
||||
const = stix2.patterns.make_constant(input_)
|
||||
|
||||
assert isinstance(const, expected_class)
|
||||
assert const.value == expected_value
|
||||
|
||||
|
||||
def test_make_constant_list():
|
||||
list_const = stix2.patterns.make_constant([1, 2, 3])
|
||||
|
||||
assert isinstance(list_const, stix2.patterns.ListConstant)
|
||||
assert all(
|
||||
isinstance(elt, stix2.patterns.IntegerConstant)
|
||||
for elt in list_const.value
|
||||
)
|
||||
assert all(
|
||||
int_const.value == test_elt
|
||||
for int_const, test_elt in zip(list_const.value, [1, 2, 3])
|
||||
)
|
||||
|
||||
|
||||
def test_make_constant_already_a_constant():
|
||||
str_const = stix2.StringConstant('Foo')
|
||||
result = stix2.patterns.make_constant(str_const)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import datetime
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
from stix2patterns.exceptions import ParseException
|
||||
|
||||
import stix2
|
||||
from stix2.pattern_visitor import create_pattern_object
|
||||
import stix2.utils
|
||||
|
||||
|
||||
def test_create_comparison_expression():
|
||||
|
@ -362,7 +364,7 @@ def test_parsing_or_observable_expression():
|
|||
assert str(exp) == "[user-account:account_type = 'unix' AND user-account:user_id = '1007' AND user-account:account_login = 'Peter'] OR [user-account:account_type = 'unix' AND user-account:user_id = '1008' AND user-account:account_login = 'Paul']" # noqa
|
||||
|
||||
|
||||
def test_invalid_and_observable_expression():
|
||||
def test_invalid_and_comparison_expression():
|
||||
with pytest.raises(ValueError):
|
||||
stix2.AndBooleanExpression([
|
||||
stix2.EqualityComparisonExpression(
|
||||
|
@ -376,6 +378,33 @@ def test_invalid_and_observable_expression():
|
|||
])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"pattern, root_types", [
|
||||
("[a:a=1 AND a:b=1]", {"a"}),
|
||||
("[a:a=1 AND a:b=1 OR c:d=1]", {"a", "c"}),
|
||||
("[a:a=1 AND (a:b=1 OR c:d=1)]", {"a"}),
|
||||
("[(a:a=1 OR b:a=1) AND (b:a=1 OR c:c=1)]", {"b"}),
|
||||
("[(a:a=1 AND a:b=1) OR (b:a=1 AND b:c=1)]", {"a", "b"}),
|
||||
],
|
||||
)
|
||||
def test_comparison_expression_root_types(pattern, root_types):
|
||||
ast = create_pattern_object(pattern)
|
||||
assert ast.operand.root_types == root_types
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"pattern", [
|
||||
"[a:b=1 AND b:c=1]",
|
||||
"[a:b=1 AND (b:c=1 OR c:d=1)]",
|
||||
"[(a:b=1 OR b:c=1) AND (c:d=1 OR d:e=1)]",
|
||||
"[(a:b=1 AND b:c=1) OR (b:c=1 AND c:d=1)]",
|
||||
],
|
||||
)
|
||||
def test_comparison_expression_root_types_error(pattern):
|
||||
with pytest.raises(ValueError):
|
||||
create_pattern_object(pattern)
|
||||
|
||||
|
||||
def test_hex():
|
||||
exp_and = stix2.AndBooleanExpression([
|
||||
stix2.EqualityComparisonExpression(
|
||||
|
@ -603,6 +632,44 @@ def test_invalid_startstop_qualifier():
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input_, expected_class, expected_value", [
|
||||
(1, stix2.patterns.IntegerConstant, 1),
|
||||
(1.5, stix2.patterns.FloatConstant, 1.5),
|
||||
("abc", stix2.patterns.StringConstant, "abc"),
|
||||
(True, stix2.patterns.BooleanConstant, True),
|
||||
(
|
||||
"2001-02-10T21:36:15Z", stix2.patterns.TimestampConstant,
|
||||
stix2.utils.STIXdatetime(2001, 2, 10, 21, 36, 15, tzinfo=pytz.utc),
|
||||
),
|
||||
(
|
||||
datetime.datetime(2001, 2, 10, 21, 36, 15, tzinfo=pytz.utc),
|
||||
stix2.patterns.TimestampConstant,
|
||||
stix2.utils.STIXdatetime(2001, 2, 10, 21, 36, 15, tzinfo=pytz.utc),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_make_constant_simple(input_, expected_class, expected_value):
|
||||
const = stix2.patterns.make_constant(input_)
|
||||
|
||||
assert isinstance(const, expected_class)
|
||||
assert const.value == expected_value
|
||||
|
||||
|
||||
def test_make_constant_list():
|
||||
list_const = stix2.patterns.make_constant([1, 2, 3])
|
||||
|
||||
assert isinstance(list_const, stix2.patterns.ListConstant)
|
||||
assert all(
|
||||
isinstance(elt, stix2.patterns.IntegerConstant)
|
||||
for elt in list_const.value
|
||||
)
|
||||
assert all(
|
||||
int_const.value == test_elt
|
||||
for int_const, test_elt in zip(list_const.value, [1, 2, 3])
|
||||
)
|
||||
|
||||
|
||||
def test_make_constant_already_a_constant():
|
||||
str_const = stix2.StringConstant('Foo')
|
||||
result = stix2.patterns.make_constant(str_const)
|
||||
|
|
Loading…
Reference in New Issue