Merge pull request #167 from oasis-open/invalid-type-names
Disallow invalid type names in custom classesstix2.0
commit
a1befe6387
|
@ -197,6 +197,24 @@ def test_custom_object_no_init_2():
|
|||
assert no2.property1 == 'something'
|
||||
|
||||
|
||||
def test_custom_object_invalid_type_name():
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.sdo.CustomObject('x', [
|
||||
('property1', stix2.properties.StringProperty(required=True)),
|
||||
])
|
||||
class NewObj(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid type name 'x': " in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.sdo.CustomObject('x_new_object', [
|
||||
('property1', stix2.properties.StringProperty(required=True)),
|
||||
])
|
||||
class NewObj2(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid type name 'x_new_object':" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_parse_custom_object_type():
|
||||
nt_string = """{
|
||||
"type": "x-new-type",
|
||||
|
@ -295,6 +313,24 @@ def test_custom_observable_object_no_init_2():
|
|||
assert no2.property1 == 'something'
|
||||
|
||||
|
||||
def test_custom_observable_object_invalid_type_name():
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.observables.CustomObservable('x', [
|
||||
('property1', stix2.properties.StringProperty()),
|
||||
])
|
||||
class NewObs(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid observable type name 'x':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.observables.CustomObservable('x_new_obs', [
|
||||
('property1', stix2.properties.StringProperty()),
|
||||
])
|
||||
class NewObs2(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid observable type name 'x_new_obs':" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_custom_observable_object_invalid_ref_property():
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.observables.CustomObservable('x-new-obs', [
|
||||
|
@ -573,6 +609,24 @@ def test_custom_extension_invalid_observable():
|
|||
assert "Custom observables must be created with the @CustomObservable decorator." in str(excinfo.value)
|
||||
|
||||
|
||||
def test_custom_extension_invalid_type_name():
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.observables.CustomExtension(stix2.File, 'x', {
|
||||
'property1': stix2.properties.StringProperty(required=True),
|
||||
})
|
||||
class FooExtension():
|
||||
pass # pragma: no cover
|
||||
assert "Invalid extension type name 'x':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.observables.CustomExtension(stix2.File, 'x_new_ext', {
|
||||
'property1': stix2.properties.StringProperty(required=True),
|
||||
})
|
||||
class BlaExtension():
|
||||
pass # pragma: no cover
|
||||
assert "Invalid extension type name 'x_new_ext':" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_custom_extension_no_properties():
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.observables.CustomExtension(stix2.DomainName, 'x-new-ext2', None)
|
||||
|
|
|
@ -18,6 +18,8 @@ NOW = object()
|
|||
# STIX object properties that cannot be modified
|
||||
STIX_UNMOD_PROPERTIES = ["created", "created_by_ref", "id", "type"]
|
||||
|
||||
TYPE_REGEX = r'^\-?[a-z0-9]+(-[a-z0-9]+)*\-?$'
|
||||
|
||||
|
||||
class STIXdatetime(dt.datetime):
|
||||
def __new__(cls, *args, **kwargs):
|
||||
|
|
|
@ -7,6 +7,7 @@ Observable and do not have a ``_type`` attribute.
|
|||
|
||||
from collections import OrderedDict
|
||||
import copy
|
||||
import re
|
||||
|
||||
from ..base import _Extension, _Observable, _STIXBase
|
||||
from ..exceptions import (AtLeastOnePropertyError, CustomContentError,
|
||||
|
@ -16,7 +17,7 @@ from ..properties import (BinaryProperty, BooleanProperty, DictionaryProperty,
|
|||
HashesProperty, HexProperty, IntegerProperty,
|
||||
ListProperty, ObjectReferenceProperty, Property,
|
||||
StringProperty, TimestampProperty, TypeProperty)
|
||||
from ..utils import _get_dict
|
||||
from ..utils import TYPE_REGEX, _get_dict
|
||||
|
||||
|
||||
class ObservableProperty(Property):
|
||||
|
@ -981,6 +982,12 @@ def CustomObservable(type='x-custom-observable', properties=None):
|
|||
|
||||
class _Custom(cls, _Observable):
|
||||
|
||||
if not re.match(TYPE_REGEX, type):
|
||||
raise ValueError("Invalid observable type name '%s': must only contain the "
|
||||
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." % type)
|
||||
elif len(type) < 3 or len(type) > 250:
|
||||
raise ValueError("Invalid observable type name '%s': must be between 3 and 250 characters." % type)
|
||||
|
||||
_type = type
|
||||
_properties = OrderedDict()
|
||||
_properties.update([
|
||||
|
@ -1054,6 +1061,12 @@ def CustomExtension(observable=None, type='x-custom-observable', properties=None
|
|||
|
||||
class _Custom(cls, _Extension):
|
||||
|
||||
if not re.match(TYPE_REGEX, type):
|
||||
raise ValueError("Invalid extension type name '%s': must only contain the "
|
||||
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." % type)
|
||||
elif len(type) < 3 or len(type) > 250:
|
||||
raise ValueError("Invalid extension type name '%s': must be between 3 and 250 characters." % type)
|
||||
|
||||
_type = type
|
||||
_properties = OrderedDict()
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"""
|
||||
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
|
||||
import stix2
|
||||
|
||||
|
@ -10,7 +11,7 @@ from ..markings import _MarkingsMixin
|
|||
from ..properties import (BooleanProperty, IDProperty, IntegerProperty,
|
||||
ListProperty, PatternProperty, ReferenceProperty,
|
||||
StringProperty, TimestampProperty, TypeProperty)
|
||||
from ..utils import NOW
|
||||
from ..utils import NOW, TYPE_REGEX
|
||||
from .common import ExternalReference, GranularMarking, KillChainPhase
|
||||
from .observables import ObservableProperty
|
||||
|
||||
|
@ -357,6 +358,13 @@ def CustomObject(type='x-custom-type', properties=None):
|
|||
def custom_builder(cls):
|
||||
|
||||
class _Custom(cls, STIXDomainObject):
|
||||
|
||||
if not re.match(TYPE_REGEX, type):
|
||||
raise ValueError("Invalid type name '%s': must only contain the "
|
||||
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." % type)
|
||||
elif len(type) < 3 or len(type) > 250:
|
||||
raise ValueError("Invalid type name '%s': must be between 3 and 250 characters." % type)
|
||||
|
||||
_type = type
|
||||
_properties = OrderedDict()
|
||||
_properties.update([
|
||||
|
|
Loading…
Reference in New Issue