Reuse reference regex to match IDs as well.
Note that this means that UUIDs will no longer be converted, even when there's an unambiguous mapping.stix2.0
parent
e749218f9b
commit
d2f703b9d0
|
@ -14,6 +14,17 @@ from .base import _STIXBase
|
|||
from .exceptions import DictionaryKeyError
|
||||
from .utils import _get_dict, parse_into_datetime
|
||||
|
||||
# This uses the regular expression for a RFC 4122, Version 4 UUID. In the
|
||||
# 8-4-4-4-12 hexadecimal representation, the first hex digit of the third
|
||||
# component must be a 4, and the first hex digit of the fourth component must be
|
||||
# 8, 9, a, or b (10xx bit pattern).
|
||||
ID_REGEX = re.compile("^[a-z0-9][a-z0-9-]+[a-z0-9]--" # object type
|
||||
"[0-9a-fA-F]{8}-"
|
||||
"[0-9a-fA-F]{4}-"
|
||||
"4[0-9a-fA-F]{3}-"
|
||||
"[89abAB][0-9a-fA-F]{3}-"
|
||||
"[0-9a-fA-F]{12}$")
|
||||
|
||||
|
||||
class Property(object):
|
||||
"""Represent a property of STIX data type.
|
||||
|
@ -171,14 +182,9 @@ class IDProperty(Property):
|
|||
def clean(self, value):
|
||||
if not value.startswith(self.required_prefix):
|
||||
raise ValueError("must start with '{0}'.".format(self.required_prefix))
|
||||
try:
|
||||
type, orig_id = value.split('--', maxsplit=1)
|
||||
new_uuid = uuid.UUID(orig_id)
|
||||
if new_uuid.variant != uuid.RFC_4122 or new_uuid.version != 4:
|
||||
raise ValueError()
|
||||
except ValueError:
|
||||
if not ID_REGEX.match(value):
|
||||
raise ValueError("must have a valid UUID after the prefix.")
|
||||
return "--".join([type, str(new_uuid)])
|
||||
return value
|
||||
|
||||
def default(self):
|
||||
return self.required_prefix + str(uuid.uuid4())
|
||||
|
@ -308,10 +314,6 @@ class HexProperty(Property):
|
|||
return value
|
||||
|
||||
|
||||
REF_REGEX = re.compile("^[a-z][a-z-]+[a-z]--[0-9a-fA-F]{8}-[0-9a-fA-F]{4}"
|
||||
"-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")
|
||||
|
||||
|
||||
class ReferenceProperty(Property):
|
||||
|
||||
def __init__(self, required=False, type=None):
|
||||
|
@ -328,7 +330,7 @@ class ReferenceProperty(Property):
|
|||
if self.type:
|
||||
if not value.startswith(self.type):
|
||||
raise ValueError("must start with '{0}'.".format(self.type))
|
||||
if not REF_REGEX.match(value):
|
||||
if not ID_REGEX.match(value):
|
||||
raise ValueError("must match <object-type>--<guid>.")
|
||||
return value
|
||||
|
||||
|
|
|
@ -123,23 +123,6 @@ def test_id_property_valid_for_type(value):
|
|||
assert IDProperty(type=type).clean(value) == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", [
|
||||
# These are all acceptable input formats that will get translated to the
|
||||
# same ID shown above
|
||||
MY_ID,
|
||||
# These formats are all used in the uuid.UUID() documentation as valid ways
|
||||
# to initialize a UUID. We are ok with accepting them, as they will
|
||||
# get coerced to the right format for an ID.
|
||||
'my-type--{232c9d3f-49fc-4440-bb01-607f638778e7}',
|
||||
'my-type--232c9d3f49fc4440bb01607f638778e7',
|
||||
'my-type--urn:uuid:232c9d3f-49fc-4440-bb01-607f638778e7',
|
||||
# The extra "--" are ignored by split() and accepted by uuid.UUID()
|
||||
'my-type--232c9d3f--49fc--4440--bb01--607f638778e7',
|
||||
])
|
||||
def test_id_property_transform(value):
|
||||
assert ID_PROP.clean(value) == MY_ID
|
||||
|
||||
|
||||
def test_id_property_wrong_type():
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
ID_PROP.clean('not-my-type--232c9d3f-49fc-4440-bb01-607f638778e7')
|
||||
|
|
Loading…
Reference in New Issue