diff --git a/convert.go b/convert.go
index a1b6875..6f252e7 100644
--- a/convert.go
+++ b/convert.go
@@ -90,6 +90,10 @@ func (b *BOM) convert(specVersion SpecVersion) {
convertVulnerabilities(b.Vulnerabilities, specVersion)
}
+ if b.Compositions != nil {
+ convertCompositions(b.Compositions, specVersion)
+ }
+
if b.ExternalReferences != nil {
convertExternalReferences(b.ExternalReferences, specVersion)
}
@@ -145,6 +149,19 @@ func componentConverter(specVersion SpecVersion) func(*Component) {
}
}
+func convertCompositions(comps *[]Composition, specVersion SpecVersion) {
+ if comps == nil {
+ return
+ }
+
+ for i := range *comps {
+ comp := &(*comps)[i]
+ if !specVersion.supportsCompositionAggregate(comp.Aggregate) {
+ comp.Aggregate = CompositionAggregateUnknown
+ }
+ }
+}
+
// convertExternalReferences modifies an ExternalReference slice such that it adheres to a given SpecVersion.
func convertExternalReferences(extRefs *[]ExternalReference, specVersion SpecVersion) {
if extRefs == nil {
@@ -342,6 +359,16 @@ func (sv SpecVersion) supportsComponentType(cType ComponentType) bool {
return false
}
+func (sv SpecVersion) supportsCompositionAggregate(ca CompositionAggregate) bool {
+ switch ca {
+ case CompositionAggregateIncompleteFirstPartyOpenSourceOnly, CompositionAggregateIncompleteFirstPartyProprietaryOnly,
+ CompositionAggregateIncompleteThirdPartyOpenSourceOnly, CompositionAggregateIncompleteThirdPartyProprietaryOnly:
+ return sv >= SpecVersion1_5
+ }
+
+ return sv >= SpecVersion1_3
+}
+
func (sv SpecVersion) supportsExternalReferenceType(ert ExternalReferenceType) bool {
switch ert {
case ERTypeAdversaryModel,
diff --git a/cyclonedx.go b/cyclonedx.go
index 08f782a..54ef21e 100644
--- a/cyclonedx.go
+++ b/cyclonedx.go
@@ -169,20 +169,26 @@ type Component struct {
}
type Composition struct {
- Aggregate CompositionAggregate `json:"aggregate" xml:"aggregate"`
- Assemblies *[]BOMReference `json:"assemblies,omitempty" xml:"assemblies>assembly,omitempty"`
- Dependencies *[]BOMReference `json:"dependencies,omitempty" xml:"dependencies>dependency,omitempty"`
+ BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"`
+ Aggregate CompositionAggregate `json:"aggregate" xml:"aggregate"`
+ Assemblies *[]BOMReference `json:"assemblies,omitempty" xml:"assemblies>assembly,omitempty"`
+ Dependencies *[]BOMReference `json:"dependencies,omitempty" xml:"dependencies>dependency,omitempty"`
+ Vulnerabilities *[]BOMReference `json:"vulnerabilities,omitempty" xml:"vulnerabilities>vulnerability,omitempty"`
}
type CompositionAggregate string
const (
- CompositionAggregateComplete CompositionAggregate = "complete"
- CompositionAggregateIncomplete CompositionAggregate = "incomplete"
- CompositionAggregateIncompleteFirstPartyOnly CompositionAggregate = "incomplete_first_party_only"
- CompositionAggregateIncompleteThirdPartyOnly CompositionAggregate = "incomplete_third_party_only"
- CompositionAggregateUnknown CompositionAggregate = "unknown"
- CompositionAggregateNotSpecified CompositionAggregate = "not_specified"
+ CompositionAggregateComplete CompositionAggregate = "complete"
+ CompositionAggregateIncomplete CompositionAggregate = "incomplete"
+ CompositionAggregateIncompleteFirstPartyOnly CompositionAggregate = "incomplete_first_party_only"
+ CompositionAggregateIncompleteFirstPartyOpenSourceOnly CompositionAggregate = "incomplete_first_party_opensource_only"
+ CompositionAggregateIncompleteFirstPartyProprietaryOnly CompositionAggregate = "incomplete_first_party_proprietary_only"
+ CompositionAggregateIncompleteThirdPartyOnly CompositionAggregate = "incomplete_third_party_only"
+ CompositionAggregateIncompleteThirdPartyOpenSourceOnly CompositionAggregate = "incomplete_third_party_opensource_only"
+ CompositionAggregateIncompleteThirdPartyProprietaryOnly CompositionAggregate = "incomplete_third_party_proprietary_only"
+ CompositionAggregateNotSpecified CompositionAggregate = "not_specified"
+ CompositionAggregateUnknown CompositionAggregate = "unknown"
)
type Copyright struct {
diff --git a/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-compositions.json b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-compositions.json
index 0bb37e0..ca75376 100644
--- a/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-compositions.json
+++ b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-compositions.json
@@ -46,6 +46,7 @@
],
"compositions": [
{
+ "bom-ref": "composition-1",
"aggregate": "complete",
"assemblies": [
"pkg:maven/partner/shaded-library@1.0"
@@ -59,6 +60,21 @@
"assemblies": [
"pkg:maven/acme/library@3.0"
]
+ },
+ {
+ "aggregate": "incomplete_first_party_only",
+ "vulnerabilities": [
+ "vulnerability-1"
+ ]
+ }
+ ],
+ "vulnerabilities": [
+ {
+ "bom-ref": "vulnerability-1",
+ "id": "ACME-12345",
+ "source": {
+ "name": "Acme Inc"
+ }
}
]
}
diff --git a/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-compositions.xml b/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-compositions.xml
index 54aea6c..34baab1 100644
--- a/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-compositions.xml
+++ b/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-compositions.xml
@@ -32,7 +32,7 @@
-
+
complete
@@ -47,5 +47,19 @@
+
+ incomplete_first_party_only
+
+
+
+
+
+
+ ACME-12345
+
+
+
diff --git a/testdata/valid-compositions.json b/testdata/valid-compositions.json
index 551834e..11c8a00 100644
--- a/testdata/valid-compositions.json
+++ b/testdata/valid-compositions.json
@@ -44,8 +44,18 @@
]
}
],
+ "vulnerabilities": [
+ {
+ "bom-ref": "vulnerability-1",
+ "id": "ACME-12345",
+ "source": {
+ "name": "Acme Inc"
+ }
+ }
+ ],
"compositions": [
{
+ "bom-ref": "composition-1",
"aggregate": "complete",
"assemblies": [
"pkg:maven/partner/shaded-library@1.0"
@@ -59,6 +69,12 @@
"assemblies": [
"pkg:maven/acme/library@3.0"
]
+ },
+ {
+ "aggregate": "incomplete_first_party_only",
+ "vulnerabilities": [
+ "vulnerability-1"
+ ]
}
]
}
diff --git a/testdata/valid-compositions.xml b/testdata/valid-compositions.xml
index 82c16c5..06800df 100644
--- a/testdata/valid-compositions.xml
+++ b/testdata/valid-compositions.xml
@@ -31,8 +31,16 @@
+
+
+ ACME-12345
+
+
+
-
+
complete
@@ -47,5 +55,11 @@
+
+ incomplete_first_party_only
+
+
+
+