fix: normalize decoded FullPath

Nothing checked that a decoded `FullPath` actually extends `RealPath` with an archive chain. The SPDX
decoder sets `FullPath` to the file name even when the name doesn't end with the comment's chain, and
syft-json takes whatever is in the document. `{RealPath: "/x", FullPath: "/x"}` and `{RealPath: "/x"}`
share an ID but are different map keys, so decoded files, unknowns and locations could fail to line
up with the same coordinates built by a resolver.

The syft-json and SPDX decoders now clear a `FullPath` that equals `RealPath` or doesn't start with
`RealPath` + `!/`.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2026-10-21 11:32:50 -04:00
parent b9fdabc2f6
commit f0129112be
5 changed files with 71 additions and 5 deletions
@@ -789,3 +789,12 @@ func Test_skipsPackagesWithGeneratedFromRelationship(t *testing.T) {
assert.NotNil(t, s.Artifacts.Packages.Package("1"))
assert.Nil(t, s.Artifacts.Packages.Package("1-src"))
}
func Test_coordinatesFromFile_nonCanonicalChainIsDropped(t *testing.T) {
// a chain the name doesn't end with leaves FullPath equal to RealPath, which must decode as a plain file
got := coordinatesFromFile("/app.jar", "archivePath: other.jar!/x", "")
assert.Equal(t, file.NewCoordinates("/app.jar", ""), got)
nested := coordinatesFromFile("/app.war!/lib/a.jar", "archivePath: lib/a.jar", "")
assert.Equal(t, file.Coordinates{RealPath: "/app.war", FullPath: "/app.war!/lib/a.jar"}, nested)
}