Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hack for issue_435 #438

Merged
merged 3 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions stix2/pattern_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import importlib
import inspect
from six import text_type

from stix2patterns.exceptions import ParseException
from stix2patterns.grammars.STIXPatternParser import TerminalNode
Expand Down Expand Up @@ -50,7 +51,7 @@ def check_for_valid_timetamp_syntax(timestamp_string):


def same_boolean_operator(current_op, op_token):
return current_op == op_token.symbol.text
return current_op == op_token.getText()


class STIXPatternVisitorForSTIX2():
Expand Down Expand Up @@ -259,6 +260,11 @@ def visitObjectPath(self, ctx):
if isinstance(next, TerminalNode):
property_path.append(self.instantiate("ListObjectPathComponent", current.property_name, next.getText()))
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:
property_path.append(current)
i += 1
Expand All @@ -272,7 +278,12 @@ def visitObjectType(self, ctx):
# Visit a parse tree produced by STIXPatternParser#firstPathComponent.
def visitFirstPathComponent(self, 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"):
# return stix2.ReferenceObjectPathComponent(step)
# else:
Expand All @@ -291,8 +302,8 @@ def visitPathStep(self, ctx):
def visitKeyPathStep(self, ctx):
children = self.visitChildren(ctx)
if isinstance(children[1], StringConstant):
# special case for hashes
return children[1].value
# special case for hashes and quoted steps
return children[1]
else:
return self.instantiate("BasicObjectPathComponent", children[1].getText(), True)

Expand Down
5 changes: 4 additions & 1 deletion stix2/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,10 @@ def make_constant(value):
class _ObjectPathComponent(object):
@staticmethod
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)
elif component_name.find("[") != -1:
parse1 = component_name.split("[")
Expand Down
20 changes: 18 additions & 2 deletions stix2/test/v20/test_pattern_expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,15 +512,31 @@ def test_parsing_start_stop_qualified_expression():


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]"


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]"


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():
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")
Expand Down
15 changes: 15 additions & 0 deletions stix2/test/v21/test_pattern_expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]"


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():
patt_obj = create_pattern_object("[ file:name = 'weird_name\\'' ]", version="2.1")
assert str(patt_obj) == "[file:name = 'weird_name\\'']"
Expand Down