diff --git a/stix2/markings/utils.py b/stix2/markings/utils.py index 538b18b4..c8c78457 100644 --- a/stix2/markings/utils.py +++ b/stix2/markings/utils.py @@ -1,6 +1,6 @@ """Utility functions for STIX2 data markings.""" -import collections +import collections.abc from stix2 import exceptions, utils @@ -232,7 +232,7 @@ def iterpath(obj, path=None): path.append(varname) yield (path, varobj) - if isinstance(varobj, dict): + if isinstance(varobj, collections.abc.Mapping): for item in iterpath(varobj, path): yield item @@ -245,7 +245,7 @@ def iterpath(obj, path=None): yield (path, item) - if isinstance(item, dict): + if isinstance(item, collections.abc.Mapping): for descendant in iterpath(item, path): yield descendant diff --git a/stix2/test/v21/test_granular_markings.py b/stix2/test/v21/test_granular_markings.py index ff8fe26d..6d405786 100644 --- a/stix2/test/v21/test_granular_markings.py +++ b/stix2/test/v21/test_granular_markings.py @@ -192,6 +192,23 @@ def test_add_marking_mark_same_property_same_marking(): assert m in after["granular_markings"] +def test_add_marking_mark_nested_sub_object_property(): + # A selector reaching into a STIX sub-object such as external_references + # is valid per STIX 2.1 section 7.2.3.1, which gives the example + # external_references.[0].source_name. + kwargs = MALWARE_KWARGS.copy() + kwargs["external_references"] = [ + {"source_name": "capec", "external_id": "CAPEC-163"}, + ] + before = Malware(**kwargs) + selector = "external_references.[0].source_name" + + after = markings.add_markings(before, [MARKING_IDS[0]], [selector]) + + assert after["granular_markings"][0]["selectors"] == [selector] + assert after["granular_markings"][0]["marking_ref"] == MARKING_IDS[0] + + @pytest.mark.parametrize( "data,marking", [ (