Repository: oasis-open/cti-python-stix2
Pull request #287 (2019-09-13 13:54:53)

Fixing precision not holding on a marking-definition during parsing and serialization


Patch:
diff --git a/stix2/v20/common.py b/stix2/v20/common.py
index 0a0cabc..a197a34 100644
--- a/stix2/v20/common.py
+++ b/stix2/v20/common.py
@@ -3,6 +3,8 @@
 from collections import OrderedDict
 import copy
 
+import six
+
 from ..base import _STIXBase
 from ..custom import _custom_marking_builder
 from ..markings import _MarkingsMixin
@@ -14,6 +16,21 @@ from ..properties import (
 from ..utils import NOW, _get_dict
 
 
+def _should_set_millisecond(cr, marking_type):
+    # TLP instances in the 2.0 spec have millisecond precision unlike other markings
+    if marking_type == TLPMarking:
+        return True
+    # otherwise,  precision is kept from how it was given
+    if isinstance(cr, six.string_types):
+        if '.' in cr:
+            return True
+        else:
+            return False
+    if cr.precision == 'millisecond':
+        return True
+    return False
+
+
 class ExternalReference(_STIXBase):
     """For more detailed information on this object's properties, see
     `the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709261>`__.
@@ -122,12 +139,12 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
             except KeyError:
                 raise ValueError("definition_type must be a valid marking type")
 
-            if marking_type == TLPMarking:
-                # TLP instances in the spec have millisecond precision unlike other markings
-                self._properties = copy.deepcopy(self._properties)
-                self._properties.update([
-                    ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
-                ])
+            if 'created' in kwargs:
+                if _should_set_millisecond(kwargs['created'], marking_type):
+                    self._properties = copy.deepcopy(self._properties)
+                    self._properties.update([
+                        ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
+                    ])
 
             if not isinstance(kwargs['definition'], marking_type):
                 defn = _get_dict(kwargs['definition'])
diff --git a/stix2/v21/common.py b/stix2/v21/common.py
index 13d0ff6..ca97597 100644
--- a/stix2/v21/common.py
+++ b/stix2/v21/common.py
@@ -1,7 +1,6 @@
 """STIX 2.1 Common Data Types and Properties."""
 
 from collections import OrderedDict
-import copy
 
 from ..base import _STIXBase
 from ..custom import _custom_marking_builder
@@ -146,7 +145,7 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
         ('spec_version', StringProperty(fixed='2.1')),
         ('id', IDProperty(_type)),
         ('created_by_ref', ReferenceProperty(type='identity')),
-        ('created', TimestampProperty(default=lambda: NOW)),
+        ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
         ('external_references', ListProperty(ExternalReference)),
         ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))),
         ('granular_markings', ListProperty(GranularMarking)),
@@ -162,13 +161,6 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
             except KeyError:
                 raise ValueError("definition_type must be a valid marking type")
 
-            if marking_type == TLPMarking:
-                # TLP instances in the spec have millisecond precision unlike other markings
-                self._properties = copy.deepcopy(self._properties)
-                self._properties.update([
-                    ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
-                ])
-
             if not isinstance(kwargs['definition'], marking_type):
                 defn = _get_dict(kwargs['definition'])
                 kwargs['definition'] = marking_type(**defn)


Test patch:
diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py
index bd247e6..1f9f5e8 100644
--- a/stix2/test/v21/test_markings.py
+++ b/stix2/test/v21/test_markings.py
@@ -25,7 +25,7 @@ EXPECTED_STATEMENT_MARKING_DEFINITION = """{
     "type": "marking-definition",
     "spec_version": "2.1",
     "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
-    "created": "2017-01-20T00:00:00Z",
+    "created": "2017-01-20T00:00:00.000Z",
     "definition_type": "statement",
     "definition": {
         "statement": "Copyright 2016, Example Corp"