Skip to content

Commit db7445c

Browse files
committed
feat: support for CycloneDX schema version 1.4.2
- Provides support for `vulnerability.properties` Signed-off-by: Paul Horton <[email protected]>
1 parent 7fb27ae commit db7445c

File tree

6 files changed

+40
-7
lines changed

6 files changed

+40
-7
lines changed

cyclonedx/model/vulnerability.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from sortedcontainers import SortedSet
2828

2929
from ..exception.model import MutuallyExclusivePropertiesException, NoPropertiesProvidedException
30-
from . import ComparableTuple, OrganizationalContact, OrganizationalEntity, Tool, XsUri
30+
from . import ComparableTuple, OrganizationalContact, OrganizationalEntity, Property, Tool, XsUri
3131
from .bom_ref import BomRef
3232
from .impact_analysis import (
3333
ImpactAnalysisAffectedStatus,
@@ -788,6 +788,7 @@ def __init__(self, *, bom_ref: Optional[str] = None, id: Optional[str] = None,
788788
credits: Optional[VulnerabilityCredits] = None,
789789
tools: Optional[Iterable[Tool]] = None, analysis: Optional[VulnerabilityAnalysis] = None,
790790
affects_targets: Optional[Iterable[BomTarget]] = None,
791+
properties: Optional[Iterable[Property]] = None,
791792
# Deprecated Parameters kept for backwards compatibility
792793
source_name: Optional[str] = None, source_url: Optional[str] = None,
793794
recommendations: Optional[Iterable[str]] = None) -> None:
@@ -808,6 +809,7 @@ def __init__(self, *, bom_ref: Optional[str] = None, id: Optional[str] = None,
808809
self.tools = tools or [] # type: ignore
809810
self.analysis = analysis
810811
self.affects = affects_targets or [] # type: ignore
812+
self.properties = properties or [] # type: ignore
811813

812814
if source_name or source_url:
813815
warnings.warn('`source_name` and `source_url` are deprecated - use `source`', DeprecationWarning)
@@ -1062,6 +1064,21 @@ def affects(self) -> "SortedSet[BomTarget]":
10621064
def affects(self, affects_targets: Iterable[BomTarget]) -> None:
10631065
self._affects = SortedSet(affects_targets)
10641066

1067+
@property
1068+
def properties(self) -> "SortedSet[Property]":
1069+
"""
1070+
Provides the ability to document properties in a key/value store. This provides flexibility to include data not
1071+
officially supported in the standard without having to use additional namespaces or create extensions.
1072+
1073+
Return:
1074+
Set of `Property`
1075+
"""
1076+
return self._properties
1077+
1078+
@properties.setter
1079+
def properties(self, properties: Iterable[Property]) -> None:
1080+
self._properties = SortedSet(properties)
1081+
10651082
def __eq__(self, other: object) -> bool:
10661083
if isinstance(other, Vulnerability):
10671084
return hash(other) == hash(self)
@@ -1079,7 +1096,7 @@ def __hash__(self) -> int:
10791096
return hash((
10801097
self.id, self.source, tuple(self.references), tuple(self.ratings), tuple(self.cwes), self.description,
10811098
self.detail, self.recommendation, tuple(self.advisories), self.created, self.published, self.updated,
1082-
self.credits, tuple(self.tools), self.analysis, tuple(self.affects)
1099+
self.credits, tuple(self.tools), self.analysis, tuple(self.affects), tuple(self.properties)
10831100
))
10841101

10851102
def __repr__(self) -> str:

cyclonedx/output/xml.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,10 @@ def _get_vulnerability_as_xml_element_post_1_4(self, vulnerability: Vulnerabilit
688688
for version in target.versions:
689689
Xml._add_bom_target_version_range(parent_element=v_target_versions_element, version=version)
690690

691+
# properties
692+
if vulnerability.properties:
693+
Xml._add_properties_element(properties=vulnerability.properties, parent_element=vulnerability_element)
694+
691695
return vulnerability_element
692696

693697
@staticmethod

tests/data.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ def get_bom_with_component_setuptools_with_vulnerability() -> Bom:
214214
version_range='49.0.0 - 54.0.0', status=ImpactAnalysisAffectedStatus.AFFECTED
215215
)]
216216
)
217-
]
217+
],
218+
properties=get_properties_1()
218219
)
219220
component.add_vulnerability(vulnerability=vulnerability)
220221
bom.components.add(component)

tests/fixtures/json/1.4/bom_setuptools_with_vulnerabilities.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@
180180
}
181181
]
182182
}
183+
],
184+
"properties": [
185+
{
186+
"name": "key1",
187+
"value": "val1"
188+
},
189+
{
190+
"name": "key2",
191+
"value": "val2"
192+
}
183193
]
184194
}
185195
]

tests/fixtures/xml/1.4/bom_setuptools_with_vulnerabilities.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@
157157
</versions>
158158
</target>
159159
</affects>
160+
<properties>
161+
<property name="key1">val1</property>
162+
<property name="key2">val2</property>
163+
</properties>
160164
</vulnerability>
161165
</vulnerabilities>
162166
</bom>

typings/sortedcontainers.pyi

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,16 @@
33
# The contents of this file were obtained from
44
# https://github.com/althonos/python-sortedcontainers/blob/d0a225d7fd0fb4c54532b8798af3cbeebf97e2d5/sortedcontainers/sortedset.pyi
55

6-
from typing import (
6+
from typing import ( # Iterator,; Tuple,; Type,
77
Any,
88
Callable,
99
Hashable,
1010
Iterable,
11-
# Iterator,
1211
List,
1312
MutableSet,
1413
Optional,
1514
Sequence,
1615
Set,
17-
# Tuple,
18-
# Type,
1916
TypeVar,
2017
Union,
2118
overload,

0 commit comments

Comments
 (0)