fix: don't infer archive nesting from paths in error text

`ProcessPathErrors` cut the `path="..."` it pulled out of an error at the first `!/` and built nested
coordinates from it, so a host file with `!/` in its name was reported as a file inside an archive.

- paths from error text are taken as plain real paths again, as on main
- the php extension reader already has the location in hand, so it records the unknown against that
  instead of re-parsing the error (this is the one caller that could see a nested path). It also
  no longer defers `Close` on a nil reader when the read fails

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2026-10-21 11:28:53 -04:00
parent 99723d91dd
commit 901d7bbab2
4 changed files with 28 additions and 14 deletions
+3 -12
View File
@@ -2,7 +2,6 @@ package unknown
import (
"regexp"
"strings"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/file"
@@ -20,7 +19,9 @@ func ProcessPathErrors(err error) error {
if pathErrorRegex.MatchString(errText) {
foundPath := pathErrorRegex.ReplaceAllString(err.Error(), "$1")
if foundPath != "" {
return New(file.NewLocationFromCoordinates(pathCoordinates(foundPath)), err)
// a path in an error text is taken as is: nesting is never inferred from "!/" in it, since a real
// path can hold one too. A caller with the location in hand should use New instead
return New(file.NewLocation(foundPath), err)
}
}
unknowns, remainingErrors := ExtractCoordinateErrors(err)
@@ -32,13 +33,3 @@ func ProcessPathErrors(err error) error {
}
return Join(out...)
}
// pathCoordinates names the file at a path from a resolver error, which for a file within an archive is
// a full path: the real path is what precedes the first archive separator.
func pathCoordinates(p string) file.Coordinates {
realPath, _, nested := strings.Cut(p, file.ArchivePathSeparator)
if !nested {
return file.NewCoordinates(p, "")
}
return file.Coordinates{RealPath: realPath, FullPath: p}
}