fix: read direct package files when decoding SPDX tag-value (#2014)

* fix: read direct package files when decoding SPDX tag-value

---------

Signed-off-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
Keith Zantow
2023-08-14 11:37:24 -04:00
committed by GitHub
parent c7fe58683d
commit b3d7ba569b
3 changed files with 176 additions and 1 deletions
@@ -286,6 +286,16 @@ func collectSyftPackages(s *sbom.SBOM, spdxIDMap map[string]any, packages []*spd
}
func collectSyftFiles(s *sbom.SBOM, spdxIDMap map[string]any, doc *spdx.Document) {
for _, p := range doc.Packages {
for _, f := range p.Files {
l := toSyftLocation(f)
spdxIDMap[string(f.FileSPDXIdentifier)] = l
s.Artifacts.FileMetadata[l.Coordinates] = toFileMetadata(f)
s.Artifacts.FileDigests[l.Coordinates] = toFileDigests(f)
}
}
for _, f := range doc.Files {
l := toSyftLocation(f)
spdxIDMap[string(f.FileSPDXIdentifier)] = l
@@ -332,7 +342,14 @@ func toFileMetadata(f *spdx.File) (meta file.Metadata) {
}
func toSyftRelationships(spdxIDMap map[string]any, doc *spdx.Document) []artifact.Relationship {
var out []artifact.Relationship
out := collectDocRelationships(spdxIDMap, doc)
out = append(out, collectPackageFileRelationships(spdxIDMap, doc)...)
return out
}
func collectDocRelationships(spdxIDMap map[string]any, doc *spdx.Document) (out []artifact.Relationship) {
for _, r := range doc.Relationships {
// FIXME what to do with r.RefA.DocumentRefID and r.RefA.SpecialID
if r.RefA.DocumentRefID != "" && requireAndTrimPrefix(r.RefA.DocumentRefID, "DocumentRef-") != string(doc.SPDXIdentifier) {
@@ -386,6 +403,30 @@ func toSyftRelationships(spdxIDMap map[string]any, doc *spdx.Document) []artifac
return out
}
// collectPackageFileRelationships add relationships for direct files
func collectPackageFileRelationships(spdxIDMap map[string]any, doc *spdx.Document) (out []artifact.Relationship) {
for _, p := range doc.Packages {
a := spdxIDMap[string(p.PackageSPDXIdentifier)]
from, fromOk := a.(pkg.Package)
if !fromOk {
continue
}
for _, f := range p.Files {
b := spdxIDMap[string(f.FileSPDXIdentifier)]
to, toLocationOk := b.(file.Location)
if !toLocationOk {
continue
}
out = append(out, artifact.Relationship{
From: from,
To: to,
Type: artifact.ContainsRelationship,
})
}
}
return out
}
func toSyftCoordinates(f *spdx.File) file.Coordinates {
const layerIDPrefix = "layerID: "
var fileSystemID string
@@ -608,3 +608,77 @@ func Test_purlValue(t *testing.T) {
})
}
}
func Test_directPackageFiles(t *testing.T) {
doc := &spdx.Document{
SPDXVersion: "SPDX-2.3",
Packages: []*spdx.Package{
{
PackageName: "some-package",
PackageSPDXIdentifier: "1",
PackageVersion: "1.0.5",
Files: []*spdx.File{
{
FileName: "some-file",
FileSPDXIdentifier: "2",
Checksums: []spdx.Checksum{
{
Algorithm: "SHA1",
Value: "a8d733c64f9123",
},
},
},
},
},
},
}
got, err := ToSyftModel(doc)
require.NoError(t, err)
p := pkg.Package{
Name: "some-package",
Version: "1.0.5",
MetadataType: pkg.UnknownMetadataType,
}
p.SetID()
f := file.Location{
LocationData: file.LocationData{
Coordinates: file.Coordinates{
RealPath: "some-file",
FileSystemID: "",
},
VirtualPath: "some-file",
},
LocationMetadata: file.LocationMetadata{
Annotations: map[string]string{},
},
}
s := &sbom.SBOM{
Artifacts: sbom.Artifacts{
Packages: pkg.NewCollection(p),
FileMetadata: map[file.Coordinates]file.Metadata{
f.Coordinates: {},
},
FileDigests: map[file.Coordinates][]file.Digest{
f.Coordinates: {
{
Algorithm: "sha1",
Value: "a8d733c64f9123",
},
},
},
},
Relationships: []artifact.Relationship{
{
From: p,
To: f,
Type: artifact.ContainsRelationship,
},
},
Source: source.Description{},
Descriptor: sbom.Descriptor{},
}
require.Equal(t, s, got)
}