diff --git a/syft/formats/common/cyclonedxhelpers/format.go b/syft/formats/common/cyclonedxhelpers/format.go index 4050188b1..d15f44a19 100644 --- a/syft/formats/common/cyclonedxhelpers/format.go +++ b/syft/formats/common/cyclonedxhelpers/format.go @@ -92,13 +92,22 @@ func toOSComponent(distro *linux.Release) []cyclonedx.Component { Name: distro.ID, Version: distro.VersionID, // TODO should we add a PURL? - CPE: distro.CPEName, + CPE: formatCPE(distro.CPEName), ExternalReferences: eRefs, Properties: properties, }, } } +func formatCPE(cpeString string) string { + cpe, err := pkg.NewCPE(cpeString) + if err != nil { + log.Debugf("skipping invalid CPE: %s", cpeString) + return "" + } + return pkg.CPEString(cpe) +} + // NewBomDescriptor returns a new BomDescriptor tailored for the current time and "syft" tool details. func toBomDescriptor(name, version string, srcMetadata source.Metadata) *cyclonedx.Metadata { return &cyclonedx.Metadata{ diff --git a/syft/formats/common/cyclonedxhelpers/format_test.go b/syft/formats/common/cyclonedxhelpers/format_test.go new file mode 100644 index 000000000..290e7152a --- /dev/null +++ b/syft/formats/common/cyclonedxhelpers/format_test.go @@ -0,0 +1,34 @@ +package cyclonedxhelpers + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_formatCPE(t *testing.T) { + tests := []struct { + cpe string + expected string + }{ + { + cpe: "cpe:2.3:o:amazon:amazon_linux:2", + expected: "cpe:2.3:o:amazon:amazon_linux:2:*:*:*:*:*:*:*", + }, + { + cpe: "cpe:/o:opensuse:leap:15.2", + expected: "cpe:2.3:o:opensuse:leap:15.2:*:*:*:*:*:*:*", + }, + { + cpe: "invalid-cpe", + expected: "", + }, + } + + for _, test := range tests { + t.Run(test.cpe, func(t *testing.T) { + out := formatCPE(test.cpe) + assert.Equal(t, test.expected, out) + }) + } +}