fix: convert file paths for spdx formats from absolute to relative (#3509)

* feat: convert file paths for spdx formats from absolute to relative
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
This commit is contained in:
Christopher Angelo Phillips 2024-12-09 13:02:54 -05:00 committed by GitHub
parent cd0900e758
commit f9e320c5b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 84 additions and 14 deletions

View File

@ -628,6 +628,12 @@ func toFiles(s sbom.SBOM) (results []*spdx.File) {
comment = fmt.Sprintf("layerID: %s", coordinates.FileSystemID) comment = fmt.Sprintf("layerID: %s", coordinates.FileSystemID)
} }
relativePath, err := convertAbsoluteToRelative(coordinates.RealPath)
if err != nil {
log.Debugf("unable to convert relative path '%s' to absolute path: %s", coordinates.RealPath, err)
relativePath = coordinates.RealPath
}
results = append(results, &spdx.File{ results = append(results, &spdx.File{
FileSPDXIdentifier: toSPDXID(coordinates), FileSPDXIdentifier: toSPDXID(coordinates),
FileComment: comment, FileComment: comment,
@ -635,7 +641,7 @@ func toFiles(s sbom.SBOM) (results []*spdx.File) {
LicenseConcluded: noAssertion, LicenseConcluded: noAssertion,
FileCopyrightText: noAssertion, FileCopyrightText: noAssertion,
Checksums: toFileChecksums(digests), Checksums: toFileChecksums(digests),
FileName: coordinates.RealPath, FileName: relativePath,
FileTypes: toFileTypes(metadata), FileTypes: toFileTypes(metadata),
LicenseInfoInFiles: []string{ // required in SPDX 2.2 LicenseInfoInFiles: []string{ // required in SPDX 2.2
helpers.NOASSERTION, helpers.NOASSERTION,
@ -833,3 +839,22 @@ func trimPatchVersion(semver string) string {
} }
return semver return semver
} }
// spdx requires that the file name field is a relative filename
// with the root of the package archive or directory
func convertAbsoluteToRelative(absPath string) (string, error) {
// Ensure the absolute path is absolute (although it should already be)
if !path.IsAbs(absPath) {
// already relative
log.Debugf("%s is already relative", absPath)
return absPath, nil
}
// we use "/" here given that we're converting absolute paths from root to relative
relPath, found := strings.CutPrefix(absPath, "/")
if !found {
return "", fmt.Errorf("error calculating relative path: %s", absPath)
}
return relPath, nil
}

View File

@ -382,6 +382,51 @@ func Test_toPackageChecksums(t *testing.T) {
} }
} }
func Test_toFiles(t *testing.T) {
tests := []struct {
name string
in sbom.SBOM
want spdx.File
}{
{
name: "File paths are converted to relative in final SPDX collection",
in: sbom.SBOM{
Source: source.Description{
Name: "alpine",
Version: "sha256:d34db33f",
Metadata: source.ImageMetadata{
UserInput: "alpine:latest",
ManifestDigest: "sha256:d34db33f",
},
},
Artifacts: sbom.Artifacts{
Packages: pkg.NewCollection(pkg.Package{
Name: "pkg-1",
Version: "version-1",
}),
FileMetadata: map[file.Coordinates]file.Metadata{
{
RealPath: "/some/path",
FileSystemID: "",
}: {
Path: "/some/path",
},
},
},
},
want: spdx.File{
FileName: "some/path",
},
},
}
for _, test := range tests {
files := toFiles(test.in)
got := files[0]
assert.Equal(t, test.want.FileName, got.FileName)
}
}
func Test_toFileTypes(t *testing.T) { func Test_toFileTypes(t *testing.T) {
tests := []struct { tests := []struct {

View File

@ -59,7 +59,7 @@
], ],
"files": [ "files": [
{ {
"fileName": "/some/file", "fileName": "some/file",
"SPDXID": "SPDXRef-File-some-file-2c5bc344430decac", "SPDXID": "SPDXRef-File-some-file-2c5bc344430decac",
"checksums": [ "checksums": [
{ {

View File

@ -89,7 +89,7 @@
], ],
"files": [ "files": [
{ {
"fileName": "/a1/f6", "fileName": "a1/f6",
"SPDXID": "SPDXRef-File-a1-f6-9c2f7510199b17f6", "SPDXID": "SPDXRef-File-a1-f6-9c2f7510199b17f6",
"fileTypes": [ "fileTypes": [
"OTHER" "OTHER"
@ -107,7 +107,7 @@
"copyrightText": "NOASSERTION" "copyrightText": "NOASSERTION"
}, },
{ {
"fileName": "/d1/f3", "fileName": "d1/f3",
"SPDXID": "SPDXRef-File-d1-f3-c6f5b29dca12661f", "SPDXID": "SPDXRef-File-d1-f3-c6f5b29dca12661f",
"fileTypes": [ "fileTypes": [
"OTHER" "OTHER"
@ -125,7 +125,7 @@
"copyrightText": "NOASSERTION" "copyrightText": "NOASSERTION"
}, },
{ {
"fileName": "/d2/f4", "fileName": "d2/f4",
"SPDXID": "SPDXRef-File-d2-f4-c641caa71518099f", "SPDXID": "SPDXRef-File-d2-f4-c641caa71518099f",
"fileTypes": [ "fileTypes": [
"OTHER" "OTHER"
@ -143,7 +143,7 @@
"copyrightText": "NOASSERTION" "copyrightText": "NOASSERTION"
}, },
{ {
"fileName": "/f1", "fileName": "f1",
"SPDXID": "SPDXRef-File-f1-5265a4dde3edbf7c", "SPDXID": "SPDXRef-File-f1-5265a4dde3edbf7c",
"fileTypes": [ "fileTypes": [
"OTHER" "OTHER"
@ -161,7 +161,7 @@
"copyrightText": "NOASSERTION" "copyrightText": "NOASSERTION"
}, },
{ {
"fileName": "/f2", "fileName": "f2",
"SPDXID": "SPDXRef-File-f2-f9e49132a4b96ccd", "SPDXID": "SPDXRef-File-f2-f9e49132a4b96ccd",
"fileTypes": [ "fileTypes": [
"OTHER" "OTHER"
@ -179,7 +179,7 @@
"copyrightText": "NOASSERTION" "copyrightText": "NOASSERTION"
}, },
{ {
"fileName": "/z1/f5", "fileName": "z1/f5",
"SPDXID": "SPDXRef-File-z1-f5-839d99ee67d9d174", "SPDXID": "SPDXRef-File-z1-f5-839d99ee67d9d174",
"fileTypes": [ "fileTypes": [
"OTHER" "OTHER"

View File

@ -10,7 +10,7 @@ Created: redacted
##### Unpackaged files ##### Unpackaged files
FileName: /a1/f6 FileName: a1/f6
SPDXID: SPDXRef-File-a1-f6-9c2f7510199b17f6 SPDXID: SPDXRef-File-a1-f6-9c2f7510199b17f6
FileType: OTHER FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000 FileChecksum: SHA1: 0000000000000000000000000000000000000000
@ -18,7 +18,7 @@ LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION FileCopyrightText: NOASSERTION
FileName: /d1/f3 FileName: d1/f3
SPDXID: SPDXRef-File-d1-f3-c6f5b29dca12661f SPDXID: SPDXRef-File-d1-f3-c6f5b29dca12661f
FileType: OTHER FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000 FileChecksum: SHA1: 0000000000000000000000000000000000000000
@ -26,7 +26,7 @@ LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION FileCopyrightText: NOASSERTION
FileName: /d2/f4 FileName: d2/f4
SPDXID: SPDXRef-File-d2-f4-c641caa71518099f SPDXID: SPDXRef-File-d2-f4-c641caa71518099f
FileType: OTHER FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000 FileChecksum: SHA1: 0000000000000000000000000000000000000000
@ -34,7 +34,7 @@ LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION FileCopyrightText: NOASSERTION
FileName: /f1 FileName: f1
SPDXID: SPDXRef-File-f1-5265a4dde3edbf7c SPDXID: SPDXRef-File-f1-5265a4dde3edbf7c
FileType: OTHER FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000 FileChecksum: SHA1: 0000000000000000000000000000000000000000
@ -42,7 +42,7 @@ LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION FileCopyrightText: NOASSERTION
FileName: /f2 FileName: f2
SPDXID: SPDXRef-File-f2-f9e49132a4b96ccd SPDXID: SPDXRef-File-f2-f9e49132a4b96ccd
FileType: OTHER FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000 FileChecksum: SHA1: 0000000000000000000000000000000000000000
@ -50,7 +50,7 @@ LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION LicenseInfoInFile: NOASSERTION
FileCopyrightText: NOASSERTION FileCopyrightText: NOASSERTION
FileName: /z1/f5 FileName: z1/f5
SPDXID: SPDXRef-File-z1-f5-839d99ee67d9d174 SPDXID: SPDXRef-File-z1-f5-839d99ee67d9d174
FileType: OTHER FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000 FileChecksum: SHA1: 0000000000000000000000000000000000000000