diff --git a/stix2/observables.py b/stix2/observables.py index bb4ea31..9c1b368 100644 --- a/stix2/observables.py +++ b/stix2/observables.py @@ -110,11 +110,9 @@ class EmailMessage(_Observable): def _check_object_constraints(self): super(EmailMessage, self)._check_object_constraints() self._check_properties_dependency(["is_multipart"], ["body_multipart"]) - if self.get("is_multipart") is False and self.get("body"): - raise DependentPropertiesError( - self.__class__, - (self.get("is_multipart"), self.get("body")) - ) + if self.get("is_multipart") is True and self.get("body"): + # 'body' MAY only be used if is_multipart is false. + raise DependentPropertiesError(self.__class__, [("is_multipart", "body")]) class ArchiveExt(_Extension): @@ -447,13 +445,13 @@ class Process(_Observable): super(Process, self)._check_object_constraints() try: self._check_at_least_one_property() - if "windows-process-ext" in self.get("extensions", []): + if "windows-process-ext" in self.get('extensions', {}): self.extensions["windows-process-ext"]._check_at_least_one_property() except AtLeastOnePropertyError as enclosing_exc: - if not hasattr(self, 'extensions'): + if 'extensions' not in self: raise enclosing_exc else: - if "windows-process-ext" in self.get("extensions", []): + if "windows-process-ext" in self.get('extensions', {}): self.extensions["windows-process-ext"]._check_at_least_one_property() diff --git a/stix2/test/test_observed_data.py b/stix2/test/test_observed_data.py index b934b31..0ed9954 100644 --- a/stix2/test/test_observed_data.py +++ b/stix2/test/test_observed_data.py @@ -294,6 +294,31 @@ def test_parse_email_message(data): assert odata.body_multipart[0].content_disposition == "inline" +@pytest.mark.parametrize("data", [ + """ + { + "type": "email-message", + "from_ref": "0", + "to_refs": ["1"], + "is_multipart": true, + "date": "1997-11-21T15:55:06.000Z", + "subject": "Saying Hello", + "body": "Cats are funny!" + } + """ +]) +def test_parse_email_message_not_multipart(data): + valid_refs = { + "0": "email-addr", + "1": "email-addr", + } + with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: + stix2.parse_observable(data, valid_refs) + + assert excinfo.value.cls == stix2.EmailMessage + assert excinfo.value.dependencies == [("is_multipart", "body")] + + @pytest.mark.parametrize("data", [ """"0": { "type": "file", @@ -913,6 +938,23 @@ def test_process_example_empty_with_extensions(): assert excinfo.value.properties == sorted(properties_of_extension) +def test_process_example_windows_process_ext(): + proc = stix2.Process(pid=314, + name="foobar.exe", + extensions={ + "windows-process-ext": { + "aslr_enabled": True, + "dep_enabled": True, + "priority": "HIGH_PRIORITY_CLASS", + "owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309" + } + }) + assert proc.extensions["windows-process-ext"].aslr_enabled + assert proc.extensions["windows-process-ext"].dep_enabled + assert proc.extensions["windows-process-ext"].priority == "HIGH_PRIORITY_CLASS" + assert proc.extensions["windows-process-ext"].owner_sid == "S-1-5-21-186985262-1144665072-74031268-1309" + + def test_process_example_windows_process_ext_empty(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: stix2.Process(pid=1221,