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
Greg Back 2018-06-27 12:27:44 -05:00
parent e749218f9b
commit d2f703b9d0
2 changed files with 14 additions and 29 deletions

View File

@ -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

View File

@ -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')