From d2f703b9d03aca552273de9a1f819bae08744f67 Mon Sep 17 00:00:00 2001 From: Greg Back Date: Wed, 27 Jun 2018 12:27:44 -0500 Subject: [PATCH] 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/properties.py | 26 ++++++++++++++------------ stix2/test/test_properties.py | 17 ----------------- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/stix2/properties.py b/stix2/properties.py index 5e6c3c3..871e8fd 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -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 --.") return value diff --git a/stix2/test/test_properties.py b/stix2/test/test_properties.py index b2e49b5..ef590c5 100644 --- a/stix2/test/test_properties.py +++ b/stix2/test/test_properties.py @@ -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')