commit
1948b38eec
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
|
from six import text_type
|
||||||
|
|
||||||
from stix2patterns.exceptions import ParseException
|
from stix2patterns.exceptions import ParseException
|
||||||
from stix2patterns.grammars.STIXPatternParser import TerminalNode
|
from stix2patterns.grammars.STIXPatternParser import TerminalNode
|
||||||
|
@ -50,7 +51,7 @@ def check_for_valid_timetamp_syntax(timestamp_string):
|
||||||
|
|
||||||
|
|
||||||
def same_boolean_operator(current_op, op_token):
|
def same_boolean_operator(current_op, op_token):
|
||||||
return current_op == op_token.symbol.text
|
return current_op == op_token.getText()
|
||||||
|
|
||||||
|
|
||||||
class STIXPatternVisitorForSTIX2():
|
class STIXPatternVisitorForSTIX2():
|
||||||
|
@ -259,6 +260,11 @@ class STIXPatternVisitorForSTIX2():
|
||||||
if isinstance(next, TerminalNode):
|
if isinstance(next, TerminalNode):
|
||||||
property_path.append(self.instantiate("ListObjectPathComponent", current.property_name, next.getText()))
|
property_path.append(self.instantiate("ListObjectPathComponent", current.property_name, next.getText()))
|
||||||
i += 2
|
i += 2
|
||||||
|
elif isinstance(next, IntegerConstant):
|
||||||
|
property_path.append(self.instantiate("ListObjectPathComponent",
|
||||||
|
current.property_name if isinstance(current, BasicObjectPathComponent) else text_type(current),
|
||||||
|
next.value))
|
||||||
|
i += 2
|
||||||
else:
|
else:
|
||||||
property_path.append(current)
|
property_path.append(current)
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -272,7 +278,12 @@ class STIXPatternVisitorForSTIX2():
|
||||||
# Visit a parse tree produced by STIXPatternParser#firstPathComponent.
|
# Visit a parse tree produced by STIXPatternParser#firstPathComponent.
|
||||||
def visitFirstPathComponent(self, ctx):
|
def visitFirstPathComponent(self, ctx):
|
||||||
children = self.visitChildren(ctx)
|
children = self.visitChildren(ctx)
|
||||||
step = children[0].getText()
|
first_component = children[0]
|
||||||
|
# hack for when the first component isn't a TerminalNode (see issue #438)
|
||||||
|
if isinstance(first_component, TerminalNode):
|
||||||
|
step = first_component.getText()
|
||||||
|
else:
|
||||||
|
step = text_type(first_component)
|
||||||
# if step.endswith("_ref"):
|
# if step.endswith("_ref"):
|
||||||
# return stix2.ReferenceObjectPathComponent(step)
|
# return stix2.ReferenceObjectPathComponent(step)
|
||||||
# else:
|
# else:
|
||||||
|
@ -291,8 +302,8 @@ class STIXPatternVisitorForSTIX2():
|
||||||
def visitKeyPathStep(self, ctx):
|
def visitKeyPathStep(self, ctx):
|
||||||
children = self.visitChildren(ctx)
|
children = self.visitChildren(ctx)
|
||||||
if isinstance(children[1], StringConstant):
|
if isinstance(children[1], StringConstant):
|
||||||
# special case for hashes
|
# special case for hashes and quoted steps
|
||||||
return children[1].value
|
return children[1]
|
||||||
else:
|
else:
|
||||||
return self.instantiate("BasicObjectPathComponent", children[1].getText(), True)
|
return self.instantiate("BasicObjectPathComponent", children[1].getText(), True)
|
||||||
|
|
||||||
|
|
|
@ -248,7 +248,10 @@ def make_constant(value):
|
||||||
class _ObjectPathComponent(object):
|
class _ObjectPathComponent(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_ObjectPathComponent(component_name):
|
def create_ObjectPathComponent(component_name):
|
||||||
if component_name.endswith("_ref"):
|
# first case is to handle if component_name was quoted
|
||||||
|
if isinstance(component_name, StringConstant):
|
||||||
|
return BasicObjectPathComponent(component_name.value, False)
|
||||||
|
elif component_name.endswith("_ref"):
|
||||||
return ReferenceObjectPathComponent(component_name)
|
return ReferenceObjectPathComponent(component_name)
|
||||||
elif component_name.find("[") != -1:
|
elif component_name.find("[") != -1:
|
||||||
parse1 = component_name.split("[")
|
parse1 = component_name.split("[")
|
||||||
|
|
|
@ -512,15 +512,31 @@ def test_parsing_start_stop_qualified_expression():
|
||||||
|
|
||||||
|
|
||||||
def test_parsing_mixed_boolean_expression_1():
|
def test_parsing_mixed_boolean_expression_1():
|
||||||
patt_obj = create_pattern_object("[a:b = 1 AND a:b = 2 OR a:b = 3]",)
|
patt_obj = create_pattern_object("[a:b = 1 AND a:b = 2 OR a:b = 3]")
|
||||||
assert str(patt_obj) == "[a:b = 1 AND a:b = 2 OR a:b = 3]"
|
assert str(patt_obj) == "[a:b = 1 AND a:b = 2 OR a:b = 3]"
|
||||||
|
|
||||||
|
|
||||||
def test_parsing_mixed_boolean_expression_2():
|
def test_parsing_mixed_boolean_expression_2():
|
||||||
patt_obj = create_pattern_object("[a:b = 1 OR a:b = 2 AND a:b = 3]",)
|
patt_obj = create_pattern_object("[a:b = 1 OR a:b = 2 AND a:b = 3]")
|
||||||
assert str(patt_obj) == "[a:b = 1 OR a:b = 2 AND a:b = 3]"
|
assert str(patt_obj) == "[a:b = 1 OR a:b = 2 AND a:b = 3]"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parsing_integer_index():
|
||||||
|
patt_obj = create_pattern_object("[a:b[1]=2]")
|
||||||
|
assert str(patt_obj) == "[a:b[1] = 2]"
|
||||||
|
|
||||||
|
|
||||||
|
# This should never occur, because the first component will always be a property_name, and they should not be quoted.
|
||||||
|
def test_parsing_quoted_first_path_component():
|
||||||
|
patt_obj = create_pattern_object("[a:'b'[1]=2]")
|
||||||
|
assert str(patt_obj) == "[a:'b'[1] = 2]"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parsing_quoted_second_path_component():
|
||||||
|
patt_obj = create_pattern_object("[a:b.'b'[1]=2]")
|
||||||
|
assert str(patt_obj) == "[a:b.'b'[1] = 2]"
|
||||||
|
|
||||||
|
|
||||||
def test_parsing_illegal_start_stop_qualified_expression():
|
def test_parsing_illegal_start_stop_qualified_expression():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
create_pattern_object("[ipv4-addr:value = '1.2.3.4'] START '2016-06-01' STOP '2017-03-12T08:30:00Z'", version="2.0")
|
create_pattern_object("[ipv4-addr:value = '1.2.3.4'] START '2016-06-01' STOP '2017-03-12T08:30:00Z'", version="2.0")
|
||||||
|
|
|
@ -654,6 +654,21 @@ def test_parsing_mixed_boolean_expression_2():
|
||||||
assert str(patt_obj) == "[a:b = 1 OR a:b = 2 AND a:b = 3]"
|
assert str(patt_obj) == "[a:b = 1 OR a:b = 2 AND a:b = 3]"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parsing_integer_index():
|
||||||
|
patt_obj = create_pattern_object("[a:b[1]=2]")
|
||||||
|
assert str(patt_obj) == "[a:b[1] = 2]"
|
||||||
|
|
||||||
|
# This should never occur, because the first component will always be a property_name, and they should not be quoted.
|
||||||
|
def test_parsing_quoted_first_path_component():
|
||||||
|
patt_obj = create_pattern_object("[a:'b'[1]=2]")
|
||||||
|
assert str(patt_obj) == "[a:'b'[1] = 2]"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parsing_quoted_second_path_component():
|
||||||
|
patt_obj = create_pattern_object("[a:b.'b'[1]=2]")
|
||||||
|
assert str(patt_obj) == "[a:b.'b'[1] = 2]"
|
||||||
|
|
||||||
|
|
||||||
def test_parsing_multiple_slashes_quotes():
|
def test_parsing_multiple_slashes_quotes():
|
||||||
patt_obj = create_pattern_object("[ file:name = 'weird_name\\'' ]", version="2.1")
|
patt_obj = create_pattern_object("[ file:name = 'weird_name\\'' ]", version="2.1")
|
||||||
assert str(patt_obj) == "[file:name = 'weird_name\\'']"
|
assert str(patt_obj) == "[file:name = 'weird_name\\'']"
|
||||||
|
|
Loading…
Reference in New Issue