From cd3b828905ec2bf0620ceab529c9f3734bcc234a Mon Sep 17 00:00:00 2001 From: Lucas Rodriguez Date: Tue, 13 Aug 2024 15:02:15 -0500 Subject: [PATCH] fix: add nil check to CycloneDX toBomProperties (#3119) Signed-off-by: Lucas Rodriguez --- .../cyclonedxhelpers/to_format_model.go | 6 +++ .../cyclonedxhelpers/to_format_model_test.go | 47 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/syft/format/common/cyclonedxhelpers/to_format_model.go b/syft/format/common/cyclonedxhelpers/to_format_model.go index e2f3a285f..ba93a367e 100644 --- a/syft/format/common/cyclonedxhelpers/to_format_model.go +++ b/syft/format/common/cyclonedxhelpers/to_format_model.go @@ -211,6 +211,12 @@ 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 nil diff --git a/syft/format/common/cyclonedxhelpers/to_format_model_test.go b/syft/format/common/cyclonedxhelpers/to_format_model_test.go index de3408082..c3ac1f3b8 100644 --- a/syft/format/common/cyclonedxhelpers/to_format_model_test.go +++ b/syft/format/common/cyclonedxhelpers/to_format_model_test.go @@ -236,6 +236,53 @@ func Test_toBomDescriptor(t *testing.T) { } } +func Test_toBomProperties(t *testing.T) { + tests := []struct { + name string + srcMetadata source.Description + props *[]cyclonedx.Property + }{ + { + name: "ImageMetadata without labels", + srcMetadata: source.Description{ + Metadata: source.ImageMetadata{ + Labels: map[string]string{}, + }, + }, + props: nil, + }, + { + name: "ImageMetadata with labels", + srcMetadata: source.Description{ + Metadata: source.ImageMetadata{ + Labels: map[string]string{ + "label1": "value1", + "label2": "value2", + }, + }, + }, + props: &[]cyclonedx.Property{ + {Name: "syft:image:labels:label1", Value: "value1"}, + {Name: "syft:image:labels:label2", Value: "value2"}, + }, + }, + { + name: "not ImageMetadata", + srcMetadata: source.Description{ + Metadata: source.FileMetadata{}, + }, + props: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + props := toBomProperties(test.srcMetadata) + require.Equal(t, test.props, props) + }) + } +} + func Test_toOsComponent(t *testing.T) { tests := []struct { name string