Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3f743e1

Browse filesBrowse files
committed
fix duplicate shorthand rels for 2.3
Signed-off-by: Brandon Lum <lumjjb@gmail.com>
1 parent 8b16c55 commit 3f743e1
Copy full SHA for 3f743e1

File tree

Expand file treeCollapse file tree

2 files changed

+166
-10
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+166
-10
lines changed

‎spdx/v2/v2_3/document.go

Copy file name to clipboardExpand all lines: spdx/v2/v2_3/document.go
+25-4Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package v2_3
55

66
import (
77
"encoding/json"
8+
"fmt"
89

910
converter "github.com/anchore/go-struct-converter"
1011

@@ -97,27 +98,47 @@ func (d *Document) UnmarshalJSON(b []byte) error {
9798

9899
*d = Document(d2)
99100

101+
relationshipExists := map[string]bool{}
102+
serializeRel := func(r *Relationship) string {
103+
return fmt.Sprintf("%v-%v->%v", common.RenderDocElementID(r.RefA), r.Relationship, common.RenderDocElementID(r.RefB))
104+
}
105+
106+
// index current list of relationships to ensure no duplication
107+
for _, r := range d.Relationships {
108+
relationshipExists[serializeRel(r)] = true
109+
}
110+
100111
// build relationships for documentDescribes field
101112
for _, id := range e.DocumentDescribes {
102-
d.Relationships = append(d.Relationships, &Relationship{
113+
r := &Relationship{
103114
RefA: common.DocElementID{
104115
ElementRefID: d.SPDXIdentifier,
105116
},
106117
RefB: id,
107118
Relationship: common.TypeRelationshipDescribe,
108-
})
119+
}
120+
121+
if !relationshipExists[serializeRel(r)] {
122+
d.Relationships = append(d.Relationships, r)
123+
relationshipExists[serializeRel(r)] = true
124+
}
109125
}
110126

127+
// build relationships for package hasFiles field
111128
// build relationships for package hasFiles field
112129
for _, p := range d.Packages {
113130
for _, f := range p.hasFiles {
114-
d.Relationships = append(d.Relationships, &Relationship{
131+
r := &Relationship{
115132
RefA: common.DocElementID{
116133
ElementRefID: p.PackageSPDXIdentifier,
117134
},
118135
RefB: f,
119136
Relationship: common.TypeRelationshipContains,
120-
})
137+
}
138+
if !relationshipExists[serializeRel(r)] {
139+
d.Relationships = append(d.Relationships, r)
140+
relationshipExists[serializeRel(r)] = true
141+
}
121142
}
122143

123144
p.hasFiles = nil

‎spdx/v2/v2_3/json/json_test.go

Copy file name to clipboardExpand all lines: spdx/v2/v2_3/json/json_test.go
+141-6Lines changed: 141 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package json
44

55
import (
66
"bytes"
7+
jsonenc "encoding/json"
78
"flag"
89
"fmt"
910
"os"
@@ -52,8 +53,8 @@ func Test_Read(t *testing.T) {
5253
return
5354
}
5455

55-
if !cmp.Equal(want, got, cmpopts.IgnoreUnexported(spdx.Package{})) {
56-
t.Errorf("got incorrect struct after parsing YAML example: %s", cmp.Diff(want, got, cmpopts.IgnoreUnexported(spdx.Package{})))
56+
if diff := cmp.Diff(want, got, cmpopts.IgnoreUnexported(spdx.Package{}), cmpopts.SortSlices(relationshipLess)); len(diff) > 0 {
57+
t.Errorf("got incorrect struct after parsing JSON example: %s", diff)
5758
return
5859
}
5960
}
@@ -81,8 +82,8 @@ func Test_Write(t *testing.T) {
8182
return
8283
}
8384

84-
if !cmp.Equal(want, got, cmpopts.IgnoreUnexported(spdx.Package{})) {
85-
t.Errorf("got incorrect struct after writing and re-parsing JSON example: %s", cmp.Diff(want, got, cmpopts.IgnoreUnexported(spdx.Package{})))
85+
if diff := cmp.Diff(want, got, cmpopts.IgnoreUnexported(spdx.Package{}), cmpopts.SortSlices(relationshipLess)); len(diff) > 0 {
86+
t.Errorf("got incorrect struct after parsing JSON example: %s", diff)
8687
return
8788
}
8889
}
@@ -139,7 +140,7 @@ func Test_ShorthandFields(t *testing.T) {
139140
}
140141
}
141142

142-
require.Equal(t, spdx.Document{
143+
want := spdx.Document{
143144
SPDXVersion: spdx.Version,
144145
DataLicense: spdx.DataLicense,
145146
SPDXIdentifier: "DOCUMENT",
@@ -190,7 +191,135 @@ func Test_ShorthandFields(t *testing.T) {
190191
Relationship: common.TypeRelationshipContains,
191192
},
192193
},
193-
}, doc)
194+
}
195+
196+
if diff := cmp.Diff(want, doc, cmpopts.IgnoreUnexported(spdx.Package{}), cmpopts.SortSlices(relationshipLess)); len(diff) > 0 {
197+
t.Errorf("got incorrect struct after parsing JSON example: %s", cmp.Diff(want, doc, cmpopts.IgnoreUnexported(spdx.Package{})))
198+
return
199+
}
200+
}
201+
202+
func Test_ShorthandFieldsNoDuplicates(t *testing.T) {
203+
contents := `{
204+
"spdxVersion": "SPDX-2.3",
205+
"dataLicense": "CC0-1.0",
206+
"SPDXID": "SPDXRef-DOCUMENT",
207+
"name": "SPDX-Tools-v2.0",
208+
"documentDescribes": [
209+
"SPDXRef-Container"
210+
],
211+
"packages": [
212+
{
213+
"name": "Container",
214+
"SPDXID": "SPDXRef-Container"
215+
},
216+
{
217+
"name": "Package-1",
218+
"SPDXID": "SPDXRef-Package-1",
219+
"versionInfo": "1.1.1",
220+
"hasFiles": [
221+
"SPDXRef-File-1",
222+
"SPDXRef-File-2"
223+
]
224+
},
225+
{
226+
"name": "Package-2",
227+
"SPDXID": "SPDXRef-Package-2",
228+
"versionInfo": "2.2.2"
229+
}
230+
],
231+
"files": [
232+
{
233+
"fileName": "./f1",
234+
"SPDXID": "SPDXRef-File-1"
235+
},
236+
{
237+
"fileName": "./f2",
238+
"SPDXID": "SPDXRef-File-2"
239+
}
240+
],
241+
"relationships": [
242+
{
243+
"spdxElementId": "SPDXRef-Package-1",
244+
"relationshipType": "CONTAINS",
245+
"relatedSpdxElement": "SPDXRef-File-1"
246+
},
247+
{
248+
"spdxElementId": "SPDXRef-Package-1",
249+
"relationshipType": "CONTAINS",
250+
"relatedSpdxElement": "SPDXRef-File-2"
251+
}
252+
]
253+
}`
254+
255+
doc := spdx.Document{}
256+
err := json.ReadInto(strings.NewReader(contents), &doc)
257+
258+
require.NoError(t, err)
259+
260+
id := func(s string) common.DocElementID {
261+
return common.DocElementID{
262+
ElementRefID: common.ElementID(s),
263+
}
264+
}
265+
266+
want := spdx.Document{
267+
SPDXVersion: spdx.Version,
268+
DataLicense: spdx.DataLicense,
269+
SPDXIdentifier: "DOCUMENT",
270+
DocumentName: "SPDX-Tools-v2.0",
271+
Packages: []*spdx.Package{
272+
{
273+
PackageName: "Container",
274+
PackageSPDXIdentifier: "Container",
275+
FilesAnalyzed: true,
276+
},
277+
{
278+
PackageName: "Package-1",
279+
PackageSPDXIdentifier: "Package-1",
280+
PackageVersion: "1.1.1",
281+
FilesAnalyzed: true,
282+
},
283+
{
284+
PackageName: "Package-2",
285+
PackageSPDXIdentifier: "Package-2",
286+
PackageVersion: "2.2.2",
287+
FilesAnalyzed: true,
288+
},
289+
},
290+
Files: []*spdx.File{
291+
{
292+
FileName: "./f1",
293+
FileSPDXIdentifier: "File-1",
294+
},
295+
{
296+
FileName: "./f2",
297+
FileSPDXIdentifier: "File-2",
298+
},
299+
},
300+
Relationships: []*spdx.Relationship{
301+
{
302+
RefA: id("DOCUMENT"),
303+
RefB: id("Container"),
304+
Relationship: common.TypeRelationshipDescribe,
305+
},
306+
{
307+
RefA: id("Package-1"),
308+
RefB: id("File-1"),
309+
Relationship: common.TypeRelationshipContains,
310+
},
311+
{
312+
RefA: id("Package-1"),
313+
RefB: id("File-2"),
314+
Relationship: common.TypeRelationshipContains,
315+
},
316+
},
317+
}
318+
319+
if diff := cmp.Diff(want, doc, cmpopts.IgnoreUnexported(spdx.Package{}), cmpopts.SortSlices(relationshipLess)); len(diff) > 0 {
320+
t.Errorf("got incorrect struct after parsing JSON example: %s", diff)
321+
return
322+
}
194323
}
195324

196325
func Test_JsonEnums(t *testing.T) {
@@ -334,3 +463,9 @@ func Test_JsonEnums(t *testing.T) {
334463
},
335464
}, doc)
336465
}
466+
467+
func relationshipLess(a, b *spdx.Relationship) bool {
468+
aStr, _ := jsonenc.Marshal(a)
469+
bStr, _ := jsonenc.Marshal(b)
470+
return string(aStr) < string(bStr)
471+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.