Skip to content

Commit

Permalink
Merge branch 'master' into extensions-string-error
Browse files Browse the repository at this point in the history
  • Loading branch information
clenk authored Jun 10, 2020
2 parents ca00b70 + 7e8177e commit dd27ee3
Show file tree
Hide file tree
Showing 14 changed files with 145 additions and 68 deletions.
2 changes: 1 addition & 1 deletion stix2validator/schemas-2.0
7 changes: 7 additions & 0 deletions stix2validator/test/v20/indicator_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,10 @@ def test_validate_parsed_json_list_additional_invalid_schema(self):
results = validate_parsed_json(objects, options)
assert results[0].is_valid
assert not results[1].is_valid

def test_pattern_custom_sco(self):
indicator = copy.deepcopy(self.valid_indicator)
indicator["pattern"] = "[x-foo-bar:bizz MATCHES 'buzz']"

self.assertTrueWithOptions(indicator)
self.assertTrueWithOptions(indicator, strict_properties=True)
8 changes: 8 additions & 0 deletions stix2validator/test/v20/marking_definition_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,11 @@ def test_marking_definition_invalid_definition(self):
marking_definition = copy.deepcopy(self.valid_marking_definition)
marking_definition['definition']['tlp'] = 21
self.assertFalseWithOptions(marking_definition)

def test_granular_marking_id_selector(self):
marking_definition = copy.deepcopy(self.valid_marking_definition)
marking_definition['granular_markings'] = [{
"marking_ref": "marking-definition--4478bf48-9af2-4afa-9fc5-7075f6af04af",
"selectors": ["id"]
}]
self.assertTrueWithOptions(marking_definition)
7 changes: 7 additions & 0 deletions stix2validator/test/v21/indicator_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,10 @@ def test_indicator_no_pattern_type(self):
del indicator["pattern_type"]

self.assertFalseWithOptions(indicator)

def test_pattern_custom_sco(self):
indicator = copy.deepcopy(self.valid_indicator)
indicator["pattern"] = "[x-foo-bar:bizz MATCHES 'buzz']"

self.assertTrueWithOptions(indicator)
self.assertTrueWithOptions(indicator, strict_properties=True)
5 changes: 5 additions & 0 deletions stix2validator/test/v21/malware_analysis_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,8 @@ def test_result(self):
self.assertFalseWithOptions(malware)
malware['result'] = "malicious"
self.assertTrueWithOptions(malware)

def test_result_and_analysis_refs(self):
malware = copy.deepcopy(self.valid_malware)
malware['analysis_sco_refs'] = ['file--1190f2c9-166f-55f1-9706-eea3971d8082']
self.assertTrueWithOptions(malware)
8 changes: 8 additions & 0 deletions stix2validator/test/v21/marking_definition_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,11 @@ def test_marking_definition_invalid_definition(self):
marking_definition = copy.deepcopy(self.valid_marking_definition)
marking_definition['definition']['tlp'] = 21
self.assertFalseWithOptions(marking_definition)

def test_granular_marking_id_selector(self):
marking_definition = copy.deepcopy(self.valid_marking_definition)
marking_definition['granular_markings'] = [{
"marking_ref": "marking-definition--4478bf48-9af2-4afa-9fc5-7075f6af04af",
"selectors": ["id"]
}]
self.assertTrueWithOptions(marking_definition)
29 changes: 17 additions & 12 deletions stix2validator/test/v21/spec_version_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,27 @@ class SpecVersionTestCases(ValidatorTest):
valid_data = json.loads(VALID_BUNDLE)
internal_options = ValidationOptions()

def test_empty(self):
def test_none(self):
# Test spec_version not specified anywhere
# Fail: defaults to a version that requires spec_version on SDO
# Pass: treated as a 2.1 bundle with a 2.0 SDO
bundle = copy.deepcopy(self.valid_data)
results = validate_parsed_json(bundle, self.internal_options)
self.assertFalse(results.is_valid)
self.assertTrue(results.is_valid)

def test_cmd(self):
# Test spec_version specified only in cmdline option
# Fail in 2.0: spec_version is required on Bundle
# Fail in 2.1: spec_version is required on SDO
# Pass in 2.1: spec_version is required on SDO but it's treated as a 2.0 SDO
for version in VERSION_NUMBERS:
bundle = copy.deepcopy(self.valid_data)
self.internal_options.version = version
results = validate_parsed_json(
bundle,
self.internal_options)
self.assertFalse(results.is_valid)
if version == "2.0":
self.assertFalse(results.is_valid)
elif version == "2.1":
self.assertTrue(results.is_valid)

def test_bundle(self):
# Test spec_version specified only on bundle
Expand All @@ -57,9 +60,9 @@ def test_bundle(self):
self.assertTrue(results.is_valid)
elif version == "2.1":
# Warn: spec_version is custom on bundle,
# Error: spec_version is required on SDO
self.assertFalse(results.is_valid)
self.assertTrue(len(results.errors) > 0)
# Pass: spec_version is missing from SDO so treated as a 2.0 SDO
self.assertTrue(results.is_valid)
self.assertTrue(len(results.errors) == 0)
self.assertTrue(len(results.warnings) == 1)

def test_object(self):
Expand Down Expand Up @@ -117,14 +120,16 @@ def test_cmd_and_bundle(self):
self.assertTrue(len(results.warnings) == 1)

elif cmd_version == "2.1" and bundle_version == "2.0":
self.assertFalse(results.is_valid)
self.assertTrue(len(results.errors) == 2)
# Pass: Treat as 2.1 bundle with 2.0 SDO
self.assertTrue(results.is_valid)
self.assertTrue(len(results.errors) == 0)
self.assertTrue(len(results.warnings) == 2)

elif cmd_version == "2.1" and bundle_version == "2.1":
self.assertFalse(results.is_valid)
# Pass: identity obj has no spec version so treated as 2.0
self.assertTrue(results.is_valid)
self.assertTrue(len(results.warnings) == 1)
self.assertTrue(len(results.errors) == 2)
self.assertTrue(len(results.errors) == 0)

def test_cmd_and_obj(self):
# Test spec_version specified in cmdline option and on SDO
Expand Down
26 changes: 1 addition & 25 deletions stix2validator/util.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import argparse
from argparse import RawDescriptionHelpFormatter
from collections import Iterable
from collections.abc import Iterable
import datetime
import errno
import os
Expand Down Expand Up @@ -478,30 +478,6 @@ def new_function(*args, **kwargs):
return inner_cyber_observable_check


def check_spec(instance, options):
""" Checks to see if there are differences in command-line option
provided spec_version and the spec_version found with bundles
and/or objects.
"""
warnings = []
if options.version:
try:
if instance['type'] == 'bundle' and 'spec_version' in instance:
if instance['spec_version'] != options.version:
warnings.append(instance['id'] + ": spec_version mismatch with supplied"
" option. Treating as {} content.".format(options.version))
if instance['type'] == 'bundle' and 'objects' in instance:
for obj in instance['objects']:
if 'spec_version' in obj:
if obj['spec_version'] != options.version:
warnings.append(obj['id'] + ": spec_version mismatch with supplied"
" option. Treating as {} content.".format(options.version))
except Exception:
pass

return warnings


def init_requests_cache(refresh_cache=False):
"""
Initializes a cache which the ``requests`` library will consult for
Expand Down
2 changes: 2 additions & 0 deletions stix2validator/v20/musts.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ def patterns(instance, options):
elif not property_format_re.match(prop):
yield PatternError("'%s' is not a valid observable property name"
% prop, instance['id'])
elif objtype not in enums.OBSERVABLE_TYPES:
continue # custom SCOs aren't required to use x_ prefix on properties
elif (all(x not in options.disabled for x in ['all', 'format-checks', 'custom-prefix']) and
not CUSTOM_PROPERTY_PREFIX_RE.match(prop)):
yield PatternError("Cyber Observable Object custom property '%s' "
Expand Down
2 changes: 1 addition & 1 deletion stix2validator/v20/shoulds.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- add the check code and name to table
"""

from collections import Iterable, Mapping
from collections.abc import Iterable, Mapping
from itertools import chain
import re

Expand Down
2 changes: 2 additions & 0 deletions stix2validator/v21/musts.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ def patterns(instance, options):
elif not PROPERTY_FORMAT_RE.match(prop):
yield PatternError("'%s' is not a valid observable property name"
% prop, instance['id'])
elif objtype not in enums.OBSERVABLE_TYPES:
continue # custom SCOs aren't required to use x_ prefix on properties
elif (all(x not in options.disabled for x in ['all', 'format-checks', 'custom-prefix']) and
not CUSTOM_PROPERTY_PREFIX_RE.match(prop)):
yield PatternError("Cyber Observable Object custom property '%s' "
Expand Down
2 changes: 1 addition & 1 deletion stix2validator/v21/shoulds.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- add the check code and name to table
"""

from collections import Iterable, Mapping
from collections.abc import Iterable, Mapping
from itertools import chain
import re
import uuid
Expand Down
Loading

0 comments on commit dd27ee3

Please sign in to comment.