Fix tests, add a loophole to allow custom content
The "loophole" occurs when an object contains an unregistered top-level extension. Since it's unregistered we can't tell if any custom properties on the object were defined in that extension so we assume that they are.pull/1/head
parent
2528077eb0
commit
94859a0daf
|
@ -69,7 +69,7 @@ class _STIXBase(collections.abc.Mapping):
|
||||||
|
|
||||||
return has_custom
|
return has_custom
|
||||||
|
|
||||||
# interproperty constraint methods
|
# inter-property constraint methods
|
||||||
|
|
||||||
def _check_mutually_exclusive_properties(self, list_of_properties, at_least_one=True):
|
def _check_mutually_exclusive_properties(self, list_of_properties, at_least_one=True):
|
||||||
current_properties = self.properties_populated()
|
current_properties = self.properties_populated()
|
||||||
|
@ -119,7 +119,7 @@ class _STIXBase(collections.abc.Mapping):
|
||||||
|
|
||||||
extra_kwargs = kwargs.keys() - self._properties.keys()
|
extra_kwargs = kwargs.keys() - self._properties.keys()
|
||||||
if extra_kwargs and issubclass(cls, stix2.v21._Extension):
|
if extra_kwargs and issubclass(cls, stix2.v21._Extension):
|
||||||
extra_kwargs = [prop for prop in extra_kwargs if prop != 'extension_type']
|
extra_kwargs = {prop for prop in extra_kwargs if prop != 'extension_type'}
|
||||||
|
|
||||||
if extra_kwargs and not allow_custom:
|
if extra_kwargs and not allow_custom:
|
||||||
ext_found = False
|
ext_found = False
|
||||||
|
@ -136,12 +136,24 @@ class _STIXBase(collections.abc.Mapping):
|
||||||
if ext_found is False:
|
if ext_found is False:
|
||||||
raise ExtraPropertiesError(cls, extra_kwargs)
|
raise ExtraPropertiesError(cls, extra_kwargs)
|
||||||
|
|
||||||
if custom_props:
|
extension_toplevel_properties = set()
|
||||||
# loophole for custom_properties...
|
unregistered_top_level_extension = False
|
||||||
|
if 'extensions' in kwargs and not isinstance(self, stix2.v20._STIXBase20):
|
||||||
|
for ext_name, ext in kwargs['extensions'].items():
|
||||||
|
if ext.get('extension_type', '') == 'toplevel-property-extension':
|
||||||
|
registered_extensions = stix2.registry.STIX2_OBJ_MAPS['2.1'].get('extensions', {})
|
||||||
|
if ext_name in registered_extensions:
|
||||||
|
registered_ext_properties = registered_extensions[ext_name]._properties.keys()
|
||||||
|
extension_toplevel_properties.update(registered_ext_properties)
|
||||||
|
else:
|
||||||
|
unregistered_top_level_extension = True
|
||||||
|
|
||||||
|
if custom_props or unregistered_top_level_extension:
|
||||||
|
# loophole for custom_properties and unregistered top-level extensions...
|
||||||
allow_custom = True
|
allow_custom = True
|
||||||
|
|
||||||
all_custom_prop_names = extra_kwargs | custom_props.keys() - \
|
all_custom_prop_names = (extra_kwargs | custom_props.keys()) - \
|
||||||
self._properties.keys()
|
self._properties.keys() - extension_toplevel_properties
|
||||||
if all_custom_prop_names:
|
if all_custom_prop_names:
|
||||||
if not isinstance(self, stix2.v20._STIXBase20):
|
if not isinstance(self, stix2.v20._STIXBase20):
|
||||||
for prop_name in all_custom_prop_names:
|
for prop_name in all_custom_prop_names:
|
||||||
|
|
|
@ -537,20 +537,6 @@ def test_extension_property_invalid3():
|
||||||
assert result[1]
|
assert result[1]
|
||||||
|
|
||||||
|
|
||||||
def test_extension_property_invalid_type():
|
|
||||||
ext_prop = ExtensionsProperty(spec_version="2.0")
|
|
||||||
with pytest.raises(CustomContentError) as excinfo:
|
|
||||||
ext_prop.clean(
|
|
||||||
{
|
|
||||||
'windows-pebinary-ext': {
|
|
||||||
'pe_type': 'exe',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
False,
|
|
||||||
)
|
|
||||||
assert "Can't parse unknown extension" in str(excinfo.value)
|
|
||||||
|
|
||||||
|
|
||||||
def test_extension_at_least_one_property_constraint():
|
def test_extension_at_least_one_property_constraint():
|
||||||
with pytest.raises(AtLeastOnePropertyError):
|
with pytest.raises(AtLeastOnePropertyError):
|
||||||
stix2.v20.TCPExt()
|
stix2.v20.TCPExt()
|
||||||
|
|
|
@ -571,20 +571,6 @@ def test_extension_property_invalid3():
|
||||||
assert result[1]
|
assert result[1]
|
||||||
|
|
||||||
|
|
||||||
def test_extension_property_invalid_type():
|
|
||||||
ext_prop = ExtensionsProperty(spec_version='2.1', enclosing_type='indicator')
|
|
||||||
with pytest.raises(CustomContentError) as excinfo:
|
|
||||||
ext_prop.clean(
|
|
||||||
{
|
|
||||||
'windows-pebinary-ext': {
|
|
||||||
'pe_type': 'exe',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
False,
|
|
||||||
)
|
|
||||||
assert "Can't parse unknown extension" in str(excinfo.value)
|
|
||||||
|
|
||||||
|
|
||||||
def test_extension_at_least_one_property_constraint():
|
def test_extension_at_least_one_property_constraint():
|
||||||
with pytest.raises(AtLeastOnePropertyError):
|
with pytest.raises(AtLeastOnePropertyError):
|
||||||
stix2.v21.TCPExt()
|
stix2.v21.TCPExt()
|
||||||
|
|
Loading…
Reference in New Issue