Merge pull request #400 from oasis-open/issue-398

fixed start/stop qualifier constant issue
Fixes #398.
pull/1/head
Chris Lenk 2020-06-05 10:57:59 -04:00 committed by GitHub
commit 41525f9be0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 14 deletions

View File

@ -40,6 +40,11 @@ def remove_terminal_nodes(parse_tree_nodes):
return values return values
_TIMESTAMP_RE = re.compile(r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,6})?Z')
def check_for_valid_timetamp_syntax(timestamp_string):
return _TIMESTAMP_RE.match(timestamp_string)
@ -214,6 +219,14 @@ class STIXPatternVisitorForSTIX2():
# Visit a parse tree produced by STIXPatternParser#startStopQualifier. # Visit a parse tree produced by STIXPatternParser#startStopQualifier.
def visitStartStopQualifier(self, ctx): def visitStartStopQualifier(self, ctx):
children = self.visitChildren(ctx) children = self.visitChildren(ctx)
# 2.0 parser will accept any string, need to make sure it is a full STIX timestamp
if isinstance(children[1], StringConstant):
if not check_for_valid_timetamp_syntax(children[1].value):
raise (ValueError("Start time is not a legal timestamp"))
if isinstance(children[3], StringConstant):
if not check_for_valid_timetamp_syntax(children[3].value):
raise (ValueError("Stop time is not a legal timestamp"))
return StartStopQualifier(children[1], children[3]) return StartStopQualifier(children[1], children[3])
# Visit a parse tree produced by STIXPatternParser#withinQualifier. # Visit a parse tree produced by STIXPatternParser#withinQualifier.

View File

@ -669,12 +669,16 @@ class StartStopQualifier(_ExpressionQualifier):
self.start_time = start_time self.start_time = start_time
elif isinstance(start_time, datetime.date): elif isinstance(start_time, datetime.date):
self.start_time = TimestampConstant(start_time) self.start_time = TimestampConstant(start_time)
elif isinstance(start_time, StringConstant):
self.start_time = StringConstant(start_time.value)
else: else:
raise ValueError("%s is not a valid argument for a Start/Stop Qualifier" % start_time) raise ValueError("%s is not a valid argument for a Start/Stop Qualifier" % start_time)
if isinstance(stop_time, TimestampConstant): if isinstance(stop_time, TimestampConstant):
self.stop_time = stop_time self.stop_time = stop_time
elif isinstance(stop_time, datetime.date): elif isinstance(stop_time, datetime.date):
self.stop_time = TimestampConstant(stop_time) self.stop_time = TimestampConstant(stop_time)
elif isinstance(stop_time, StringConstant):
self.stop_time = StringConstant(stop_time.value)
else: else:
raise ValueError("%s is not a valid argument for a Start/Stop Qualifier" % stop_time) raise ValueError("%s is not a valid argument for a Start/Stop Qualifier" % stop_time)

View File

@ -312,8 +312,8 @@ def test_set_op():
def test_timestamp(): def test_timestamp():
ts = stix2.TimestampConstant('2014-01-13T07:03:17Z') ts = stix2.StringConstant('2014-01-13T07:03:17Z')
assert str(ts) == "t'2014-01-13T07:03:17Z'" assert str(ts) == "'2014-01-13T07:03:17Z'"
def test_boolean(): def test_boolean():
@ -363,11 +363,6 @@ def test_invalid_integer_constant():
stix2.IntegerConstant('foo') stix2.IntegerConstant('foo')
def test_invalid_timestamp_constant():
with pytest.raises(ValueError):
stix2.TimestampConstant('foo')
def test_invalid_float_constant(): def test_invalid_float_constant():
with pytest.raises(ValueError): with pytest.raises(ValueError):
stix2.FloatConstant('foo') stix2.FloatConstant('foo')
@ -461,23 +456,23 @@ def test_invalid_within_qualifier():
def test_startstop_qualifier(): def test_startstop_qualifier():
qual = stix2.StartStopQualifier( qual = stix2.StartStopQualifier(
stix2.TimestampConstant('2016-06-01T00:00:00Z'), stix2.StringConstant('2016-06-01T00:00:00Z'),
datetime.datetime(2017, 3, 12, 8, 30, 0), stix2.StringConstant('2017-03-12T08:30:00Z'),
) )
assert str(qual) == "START t'2016-06-01T00:00:00Z' STOP t'2017-03-12T08:30:00Z'" assert str(qual) == "START '2016-06-01T00:00:00Z' STOP '2017-03-12T08:30:00Z'"
qual2 = stix2.StartStopQualifier( qual2 = stix2.StartStopQualifier(
datetime.date(2016, 6, 1), stix2.StringConstant("2016-06-01T00:00:00Z"),
stix2.TimestampConstant('2016-07-01T00:00:00Z'), stix2.StringConstant('2016-07-01T00:00:00Z'),
) )
assert str(qual2) == "START t'2016-06-01T00:00:00Z' STOP t'2016-07-01T00:00:00Z'" assert str(qual2) == "START '2016-06-01T00:00:00Z' STOP '2016-07-01T00:00:00Z'"
def test_invalid_startstop_qualifier(): def test_invalid_startstop_qualifier():
with pytest.raises(ValueError): with pytest.raises(ValueError):
stix2.StartStopQualifier( stix2.StartStopQualifier(
'foo', 'foo',
stix2.TimestampConstant('2016-06-01T00:00:00Z'), stix2.StringConstant('2016-06-01T00:00:00Z'),
) )
with pytest.raises(ValueError): with pytest.raises(ValueError):
@ -508,6 +503,19 @@ def test_parsing_qualified_expression():
) == "[network-traffic:dst_ref.type = 'domain-name' AND network-traffic:dst_ref.value = 'example.com'] REPEATS 5 TIMES WITHIN 1800 SECONDS" ) == "[network-traffic:dst_ref.type = 'domain-name' AND network-traffic:dst_ref.value = 'example.com'] REPEATS 5 TIMES WITHIN 1800 SECONDS"
def test_parsing_start_stop_qualified_expression():
patt_obj = create_pattern_object("[ipv4-addr:value = '1.2.3.4'] START '2016-06-01T00:00:00Z' STOP '2017-03-12T08:30:00Z'", version="2.0")
assert str(
patt_obj,
) == "[ipv4-addr:value = '1.2.3.4'] START '2016-06-01T00:00:00Z' STOP '2017-03-12T08:30:00Z'"
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")
def test_list_constant(): def test_list_constant():
patt_obj = create_pattern_object("[network-traffic:src_ref.value IN ('10.0.0.0', '10.0.0.1', '10.0.0.2')]", version="2.0") patt_obj = create_pattern_object("[network-traffic:src_ref.value IN ('10.0.0.0', '10.0.0.1', '10.0.0.2')]", version="2.0")
assert str(patt_obj) == "[network-traffic:src_ref.value IN ('10.0.0.0', '10.0.0.1', '10.0.0.2')]" assert str(patt_obj) == "[network-traffic:src_ref.value IN ('10.0.0.0', '10.0.0.1', '10.0.0.2')]"