From 823723f5108d14a54f5ea7e3efaf7c3e91d31301 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Mon, 24 Feb 2025 20:46:46 -0500 Subject: [PATCH] fix: typed nil hashes in cyclonedx Signed-off-by: Keith Zantow --- .../cyclonedxhelpers/to_format_model.go | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/syft/format/common/cyclonedxhelpers/to_format_model.go b/syft/format/common/cyclonedxhelpers/to_format_model.go index d3dc1b776..bea9d727a 100644 --- a/syft/format/common/cyclonedxhelpers/to_format_model.go +++ b/syft/format/common/cyclonedxhelpers/to_format_model.go @@ -70,27 +70,16 @@ func ToFormatModel(s sbom.SBOM) *cyclonedx.BOM { continue } metadata = &fileMetadata - - // Digests - var digests []file.Digest - if digestsForLocation, exists := artifacts.FileDigests[coordinate]; exists { - digests = digestsForLocation - } - - cdxHashes := digestsToHashes(digests) components = append(components, cyclonedx.Component{ BOMRef: string(coordinate.ID()), Type: cyclonedx.ComponentTypeFile, Name: metadata.Path, - Hashes: &cdxHashes, + Hashes: slicePtr(digestsToHashes(artifacts.FileDigests[coordinate])), }) } - cdxBOM.Components = &components + cdxBOM.Components = slicePtr(components) - dependencies := toDependencies(s.Relationships) - if len(dependencies) > 0 { - cdxBOM.Dependencies = &dependencies - } + cdxBOM.Dependencies = slicePtr(toDependencies(s.Relationships)) return cdxBOM } @@ -277,14 +266,7 @@ func toDependencies(relationships []artifact.Relationship) []cyclonedx.Dependenc func toBomProperties(srcMetadata source.Description) *[]cyclonedx.Property { metadata, ok := srcMetadata.Metadata.(source.ImageMetadata) if ok { - props := helpers.EncodeProperties(metadata.Labels, "syft:image:labels") - // return nil if props is nil to avoid creating a pointer to a nil slice, - // which results in a null JSON value that does not comply with the CycloneDX schema. - // https://github.com/anchore/grype/issues/1759 - if props == nil { - return nil - } - return &props + return slicePtr(helpers.EncodeProperties(metadata.Labels, "syft:image:labels")) } return nil } @@ -344,3 +326,14 @@ func toBomDescriptorComponent(srcMetadata source.Description) *cyclonedx.Compone return nil } + +// Every slice pointer needs to either be a valid slice or nil, +// otherwise we will create a pointer that is not nil but references +// a nil slice, which results in a `null` JSON value that does not +// comply with the CycloneDX schema. See: https://github.com/anchore/grype/issues/1759 +func slicePtr[T any](values []T) *[]T { + if len(values) == 0 { + return nil + } + return &values +}