mirror of
https://github.com/anchore/syft.git
synced 2026-11-04 00:16:38 +01:00
Update cyclonedx to v1.4 (#820)
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
package cyclonedxxml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_decodeXML(t *testing.T) {
|
||||
tests := []struct {
|
||||
file string
|
||||
err bool
|
||||
distro string
|
||||
packages []string
|
||||
}{
|
||||
{
|
||||
file: "snapshot/TestCycloneDxDirectoryEncoder.golden",
|
||||
distro: "debian:1.2.3",
|
||||
packages: []string{"package-1:1.0.1", "package-2:2.0.1"},
|
||||
},
|
||||
{
|
||||
file: "snapshot/TestCycloneDxImageEncoder.golden",
|
||||
distro: "debian:1.2.3",
|
||||
packages: []string{"package-1:1.0.1", "package-2:2.0.1"},
|
||||
},
|
||||
{
|
||||
file: "image-simple/Dockerfile",
|
||||
err: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.file, func(t *testing.T) {
|
||||
reader, err := os.Open("test-fixtures/" + test.file)
|
||||
assert.NoError(t, err)
|
||||
|
||||
if test.err {
|
||||
err = Format().Validate(reader)
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
bom, err := Format().Decode(reader)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
split := strings.SplitN(test.distro, ":", 2)
|
||||
name := split[0]
|
||||
version := split[1]
|
||||
assert.Equal(t, bom.Artifacts.LinuxDistribution.ID, name)
|
||||
assert.Equal(t, bom.Artifacts.LinuxDistribution.Version, version)
|
||||
|
||||
pkgs:
|
||||
for _, pkg := range test.packages {
|
||||
split = strings.SplitN(pkg, ":", 2)
|
||||
name = split[0]
|
||||
version = split[1]
|
||||
for p := range bom.Artifacts.PackageCatalog.Enumerate() {
|
||||
if p.Name == name {
|
||||
assert.Equal(t, version, p.Version)
|
||||
continue pkgs
|
||||
}
|
||||
}
|
||||
assert.Fail(t, fmt.Sprintf("package should be present: %s", pkg))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cyclonedxxml
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/anchore/syft/internal/formats/common/cyclonedxhelpers"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
)
|
||||
|
||||
func encoder(output io.Writer, s sbom.SBOM) error {
|
||||
bom := cyclonedxhelpers.ToFormatModel(s)
|
||||
enc := cyclonedx.NewBOMEncoder(output, cyclonedx.BOMFileFormatXML)
|
||||
enc.SetPretty(true)
|
||||
|
||||
err := enc.Encode(bom)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cyclonedxxml
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/internal/formats/common/testutils"
|
||||
)
|
||||
|
||||
var updateCycloneDx = flag.Bool("update-cyclonedx", false, "update the *.golden files for cyclone-dx encoders")
|
||||
|
||||
func TestCycloneDxDirectoryEncoder(t *testing.T) {
|
||||
testutils.AssertEncoderAgainstGoldenSnapshot(t,
|
||||
Format(),
|
||||
testutils.DirectoryInput(t),
|
||||
*updateCycloneDx,
|
||||
cycloneDxRedactor,
|
||||
)
|
||||
}
|
||||
|
||||
func TestCycloneDxImageEncoder(t *testing.T) {
|
||||
testImage := "image-simple"
|
||||
testutils.AssertEncoderAgainstGoldenImageSnapshot(t,
|
||||
Format(),
|
||||
testutils.ImageInput(t, testImage),
|
||||
testImage,
|
||||
*updateCycloneDx,
|
||||
cycloneDxRedactor,
|
||||
)
|
||||
}
|
||||
|
||||
func cycloneDxRedactor(s []byte) []byte {
|
||||
serialPattern := regexp.MustCompile(`serialNumber="[a-zA-Z0-9\-:]+"`)
|
||||
rfc3339Pattern := regexp.MustCompile(`([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))`)
|
||||
sha256Pattern := regexp.MustCompile(`sha256:[A-Fa-f0-9]{64}`)
|
||||
|
||||
for _, pattern := range []*regexp.Regexp{serialPattern, rfc3339Pattern, sha256Pattern} {
|
||||
s = pattern.ReplaceAll(s, []byte("redacted"))
|
||||
}
|
||||
|
||||
// the bom-ref will be autogenerated every time, the value here should not be directly tested in snapshot tests
|
||||
bomRefPattern := regexp.MustCompile(` bom-ref="[a-zA-Z0-9\-:]+"`)
|
||||
bomRef3339Pattern := regexp.MustCompile(`([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))`)
|
||||
for _, pattern := range []*regexp.Regexp{bomRefPattern, bomRef3339Pattern} {
|
||||
s = pattern.ReplaceAll(s, []byte(""))
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cyclonedxxml
|
||||
|
||||
import (
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/anchore/syft/internal/formats/common/cyclonedxhelpers"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
)
|
||||
|
||||
const ID sbom.FormatID = "cyclonedx-1-xml"
|
||||
|
||||
func Format() sbom.Format {
|
||||
return sbom.NewFormat(
|
||||
ID,
|
||||
encoder,
|
||||
cyclonedxhelpers.GetDecoder(cyclonedx.BOMFileFormatXML),
|
||||
cyclonedxhelpers.GetValidator(cyclonedx.BOMFileFormatXML),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# Note: changes to this file will result in updating several test values. Consider making a new image fixture instead of editing this one.
|
||||
FROM scratch
|
||||
ADD file-1.txt /somefile-1.txt
|
||||
ADD file-2.txt /somefile-2.txt
|
||||
@@ -0,0 +1 @@
|
||||
this file has contents
|
||||
@@ -0,0 +1 @@
|
||||
file-2 contents!
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" serialNumber="urn:uuid:892f8304-0142-45b1-b411-cade3c53057f" version="1">
|
||||
<metadata>
|
||||
<timestamp>2022-03-08T12:30:33Z</timestamp>
|
||||
<tools>
|
||||
<tool>
|
||||
<vendor>anchore</vendor>
|
||||
<name>syft</name>
|
||||
<version>[not provided]</version>
|
||||
</tool>
|
||||
</tools>
|
||||
<component bom-ref="163686ac6e30c752" type="file">
|
||||
<name>/some/path</name>
|
||||
</component>
|
||||
</metadata>
|
||||
<components>
|
||||
<component type="library">
|
||||
<name>package-1</name>
|
||||
<version>1.0.1</version>
|
||||
<licenses>
|
||||
<license>
|
||||
<id>MIT</id>
|
||||
</license>
|
||||
</licenses>
|
||||
<cpe>cpe:2.3:*:some:package:2:*:*:*:*:*:*:*</cpe>
|
||||
<purl>a-purl-2</purl>
|
||||
<properties>
|
||||
<property name="syft:package:foundBy">the-cataloger-1</property>
|
||||
<property name="syft:package:language">python</property>
|
||||
<property name="syft:package:metadataType">PythonPackageMetadata</property>
|
||||
<property name="syft:package:type">python</property>
|
||||
<property name="syft:location:0:path">/some/path/pkg1</property>
|
||||
</properties>
|
||||
</component>
|
||||
<component type="library">
|
||||
<name>package-2</name>
|
||||
<version>2.0.1</version>
|
||||
<cpe>cpe:2.3:*:some:package:2:*:*:*:*:*:*:*</cpe>
|
||||
<purl>a-purl-2</purl>
|
||||
<properties>
|
||||
<property name="syft:package:foundBy">the-cataloger-2</property>
|
||||
<property name="syft:package:metadataType">DpkgMetadata</property>
|
||||
<property name="syft:package:type">deb</property>
|
||||
<property name="syft:location:0:path">/some/path/pkg1</property>
|
||||
<property name="syft:metadata:installedSize">0</property>
|
||||
</properties>
|
||||
</component>
|
||||
<component type="operating-system">
|
||||
<name>debian</name>
|
||||
<version>1.2.3</version>
|
||||
<description>debian</description>
|
||||
<swid tagId="debian" name="debian" version="1.2.3"></swid>
|
||||
<properties>
|
||||
<property name="syft:distro:id">debian</property>
|
||||
<property name="syft:distro:idLike:0">like!</property>
|
||||
<property name="syft:distro:prettyName">debian</property>
|
||||
<property name="syft:distro:versionID">1.2.3</property>
|
||||
</properties>
|
||||
</component>
|
||||
</components>
|
||||
</bom>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" serialNumber="urn:uuid:5fa94827-eb85-4f32-a62d-76fb6e89a2dd" version="1">
|
||||
<metadata>
|
||||
<timestamp>2022-03-08T12:30:33Z</timestamp>
|
||||
<tools>
|
||||
<tool>
|
||||
<vendor>anchore</vendor>
|
||||
<name>syft</name>
|
||||
<version>[not provided]</version>
|
||||
</tool>
|
||||
</tools>
|
||||
<component bom-ref="711095b1cdf90cce" type="container">
|
||||
<name>user-image-input</name>
|
||||
<version>sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368</version>
|
||||
</component>
|
||||
</metadata>
|
||||
<components>
|
||||
<component type="library">
|
||||
<name>package-1</name>
|
||||
<version>1.0.1</version>
|
||||
<licenses>
|
||||
<license>
|
||||
<id>MIT</id>
|
||||
</license>
|
||||
</licenses>
|
||||
<cpe>cpe:2.3:*:some:package:1:*:*:*:*:*:*:*</cpe>
|
||||
<purl>a-purl-1</purl>
|
||||
<properties>
|
||||
<property name="syft:package:foundBy">the-cataloger-1</property>
|
||||
<property name="syft:package:language">python</property>
|
||||
<property name="syft:package:metadataType">PythonPackageMetadata</property>
|
||||
<property name="syft:package:type">python</property>
|
||||
<property name="syft:location:0:layerID">sha256:16e64541f2ddf59a90391ce7bb8af90313f7d373f2105d88f3d3267b72e0ebab</property>
|
||||
<property name="syft:location:0:path">/somefile-1.txt</property>
|
||||
</properties>
|
||||
</component>
|
||||
<component type="library">
|
||||
<name>package-2</name>
|
||||
<version>2.0.1</version>
|
||||
<cpe>cpe:2.3:*:some:package:2:*:*:*:*:*:*:*</cpe>
|
||||
<purl>a-purl-2</purl>
|
||||
<properties>
|
||||
<property name="syft:package:foundBy">the-cataloger-2</property>
|
||||
<property name="syft:package:metadataType">DpkgMetadata</property>
|
||||
<property name="syft:package:type">deb</property>
|
||||
<property name="syft:location:0:layerID">sha256:de6c235f76ea24c8503ec08891445b5d6a8bdf8249117ed8d8b0b6fb3ebe4f67</property>
|
||||
<property name="syft:location:0:path">/somefile-2.txt</property>
|
||||
<property name="syft:metadata:installedSize">0</property>
|
||||
</properties>
|
||||
</component>
|
||||
<component type="operating-system">
|
||||
<name>debian</name>
|
||||
<version>1.2.3</version>
|
||||
<description>debian</description>
|
||||
<swid tagId="debian" name="debian" version="1.2.3"></swid>
|
||||
<properties>
|
||||
<property name="syft:distro:id">debian</property>
|
||||
<property name="syft:distro:idLike:0">like!</property>
|
||||
<property name="syft:distro:prettyName">debian</property>
|
||||
<property name="syft:distro:versionID">1.2.3</property>
|
||||
</properties>
|
||||
</component>
|
||||
</components>
|
||||
</bom>
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user