From 24bd8292931996c43115c277ec058bf1eb1d8f60 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Mon, 20 May 2024 16:35:17 -0400 Subject: [PATCH] fix: panic if null relationship when decoding 2.2/2.3 JSON Signed-off-by: Keith Zantow --- spdx/v2/v2_2/document.go | 8 +++ spdx/v2/v2_2/json/json_test.go | 19 +++++++ .../testdata/spdx-null-relationships.json | 56 +++++++++++++++++++ spdx/v2/v2_3/document.go | 8 +++ spdx/v2/v2_3/json/json_test.go | 19 +++++++ .../testdata/spdx-null-relationships.json | 56 +++++++++++++++++++ 6 files changed, 166 insertions(+) create mode 100644 spdx/v2/v2_2/json/testdata/spdx-null-relationships.json create mode 100644 spdx/v2/v2_3/json/testdata/spdx-null-relationships.json diff --git a/spdx/v2/v2_2/document.go b/spdx/v2/v2_2/document.go index c7dae44..5fcd33a 100644 --- a/spdx/v2/v2_2/document.go +++ b/spdx/v2/v2_2/document.go @@ -120,6 +120,14 @@ func (d *Document) UnmarshalJSON(b []byte) error { return fmt.Sprintf("%v-%v->%v", common.RenderDocElementID(refA), rel, common.RenderDocElementID(refB)) } + // remove null relationships + for i := 0; i < len(d.Relationships); i++ { + if d.Relationships[i] == nil { + d.Relationships = append(d.Relationships[0:i], d.Relationships[i+1:]...) + i-- + } + } + // index current list of relationships to ensure no duplication for _, r := range d.Relationships { relationshipExists[serializeRel(r)] = true diff --git a/spdx/v2/v2_2/json/json_test.go b/spdx/v2/v2_2/json/json_test.go index c84c0ad..695549e 100644 --- a/spdx/v2/v2_2/json/json_test.go +++ b/spdx/v2/v2_2/json/json_test.go @@ -40,6 +40,25 @@ func TestLoad(t *testing.T) { } } +func Test_nullRelationships(t *testing.T) { + file, err := os.Open("testdata/spdx-null-relationships.json") + if err != nil { + panic(fmt.Errorf("error opening File: %s", err)) + } + + var got spdx.Document + err = json.ReadInto(file, &got) + if err != nil { + t.Errorf("json.parser.Load() error = %v", err) + return + } + + require.Len(t, got.Relationships, 2) + for _, r := range got.Relationships { + require.NotNil(t, r) + } +} + func Test_Write(t *testing.T) { want := example.Copy() diff --git a/spdx/v2/v2_2/json/testdata/spdx-null-relationships.json b/spdx/v2/v2_2/json/testdata/spdx-null-relationships.json new file mode 100644 index 0000000..555353d --- /dev/null +++ b/spdx/v2/v2_2/json/testdata/spdx-null-relationships.json @@ -0,0 +1,56 @@ +{ + "files": [ { + "fileName": "./Microsoft.CSharp.dll", + "SPDXID": "SPDXRef-File--Microsoft.CSharp.dll-E226415EEA8ABBBA041A635582440F75E873395C", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "696b0b0d6ac06e620efd58db6f5f2e15fa2c9b91ddf8774ab8768c958d593254" + }, + { + "algorithm": "SHA1", + "checksumValue": "e226415eea8abbba041a635582440f75e873395c" + } + ], + "licenseConcluded": "NOASSERTION", + "licenseInfoInFile": [ + "NOASSERTION" + ], + "copyrightText": "NOASSERTION" + }], + "packages": [ + { + "name": "read-pkg", + "SPDXID": "SPDXRef-Package-read-pkg-1.1.0-30839A4052AC42B4E1CAB4B52EBC7DE7B94BB36D", + "versionInfo": "1.1.0" + }, + { + "name": "read-pkg", + "SPDXID": "SPDXRef-Package-read-pkg-1.1.0-30839A4052AC42B4E1CAB4B52EBC7DE7B94BB36D", + "versionInfo": "1.1.0" + } + ], + "relationships": [ + null, + { + + }, + null, + { + + }, + null + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Coordinated Packages 229170", + "documentNamespace": "https://sbom.microsoft/1:2QSF7qZlbE-F7QrUJlEo7g:pHp_nUFvDUijZ4LrJ4RhoQ/696:229170/F8kPc6dwY0WXD1Rkc2z6cg", + "creationInfo": { + "created": "2021-12-08T21:06:16Z", + "creators": [ + "Organization: Microsoft", + "Tool: Microsoft.SBOMTool-2.0.88" + ] + } +} diff --git a/spdx/v2/v2_3/document.go b/spdx/v2/v2_3/document.go index 7350192..62b7619 100644 --- a/spdx/v2/v2_3/document.go +++ b/spdx/v2/v2_3/document.go @@ -119,6 +119,14 @@ func (d *Document) UnmarshalJSON(b []byte) error { return fmt.Sprintf("%v-%v->%v", common.RenderDocElementID(refA), rel, common.RenderDocElementID(refB)) } + // remove null relationships + for i := 0; i < len(d.Relationships); i++ { + if d.Relationships[i] == nil { + d.Relationships = append(d.Relationships[0:i], d.Relationships[i+1:]...) + i-- + } + } + // index current list of relationships to ensure no duplication for _, r := range d.Relationships { relationshipExists[serializeRel(r)] = true diff --git a/spdx/v2/v2_3/json/json_test.go b/spdx/v2/v2_3/json/json_test.go index b7b004a..1fc6008 100644 --- a/spdx/v2/v2_3/json/json_test.go +++ b/spdx/v2/v2_3/json/json_test.go @@ -88,6 +88,25 @@ func Test_Write(t *testing.T) { } } +func Test_nullRelationships(t *testing.T) { + file, err := os.Open("testdata/spdx-null-relationships.json") + if err != nil { + panic(fmt.Errorf("error opening File: %s", err)) + } + + var got spdx.Document + err = json.ReadInto(file, &got) + if err != nil { + t.Errorf("json.parser.Load() error = %v", err) + return + } + + require.Len(t, got.Relationships, 2) + for _, r := range got.Relationships { + require.NotNil(t, r) + } +} + func Test_ShorthandFields(t *testing.T) { contents := `{ "spdxVersion": "SPDX-2.3", diff --git a/spdx/v2/v2_3/json/testdata/spdx-null-relationships.json b/spdx/v2/v2_3/json/testdata/spdx-null-relationships.json new file mode 100644 index 0000000..e32cfaf --- /dev/null +++ b/spdx/v2/v2_3/json/testdata/spdx-null-relationships.json @@ -0,0 +1,56 @@ +{ + "files": [ { + "fileName": "./Microsoft.CSharp.dll", + "SPDXID": "SPDXRef-File--Microsoft.CSharp.dll-E226415EEA8ABBBA041A635582440F75E873395C", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "696b0b0d6ac06e620efd58db6f5f2e15fa2c9b91ddf8774ab8768c958d593254" + }, + { + "algorithm": "SHA1", + "checksumValue": "e226415eea8abbba041a635582440f75e873395c" + } + ], + "licenseConcluded": "NOASSERTION", + "licenseInfoInFile": [ + "NOASSERTION" + ], + "copyrightText": "NOASSERTION" + }], + "packages": [ + { + "name": "read-pkg", + "SPDXID": "SPDXRef-Package-read-pkg-1.1.0-30839A4052AC42B4E1CAB4B52EBC7DE7B94BB36D", + "versionInfo": "1.1.0" + }, + { + "name": "read-pkg", + "SPDXID": "SPDXRef-Package-read-pkg-1.1.0-30839A4052AC42B4E1CAB4B52EBC7DE7B94BB36D", + "versionInfo": "1.1.0" + } + ], + "relationships": [ + null, + { + + }, + null, + { + + }, + null + ], + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "Coordinated Packages 229170", + "documentNamespace": "https://sbom.microsoft/1:2QSF7qZlbE-F7QrUJlEo7g:pHp_nUFvDUijZ4LrJ4RhoQ/696:229170/F8kPc6dwY0WXD1Rkc2z6cg", + "creationInfo": { + "created": "2021-12-08T21:06:16Z", + "creators": [ + "Organization: Microsoft", + "Tool: Microsoft.SBOMTool-2.0.88" + ] + } +}