mirror of
https://github.com/anchore/syft.git
synced 2026-10-11 21:57:22 +02:00
* test: add windows unit test job and capture dir resolver path bug - add a `Unit tests (Windows)` job running a new `make unit:windows` task, scoped to the packages that own host path handling (tests needing linux docker fixtures are skipped) - `Unit tests` is now a gate job over the Linux and Windows unit jobs - add a resolver test asserting that locations from `AllLocations` resolve again via `FilesByPath` and use posix paths. This is expected to fail on windows today, which is why file digests come back empty for `dir:` scans (#5325) - fix windows-only test files that no longer compiled Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * chore: drop verbose output from integration tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix: windows path handling outside of the file lookup bug - chroot paths are always posix (`ToChrootPath` no longer returns backslash paths on windows), same for the directory source name derived from `base` - `windows.FromPosix` no longer panics on input that isn't volume-encoded (e.g. relative or already native paths) - skip tests on windows that rely on symlink fixtures, shell script fixtures, or emulate windows paths on a posix host - disable `core.autocrlf` on the windows CI job so fixture digests match linux This leaves only the `FilesByPath` lookup failures from #5325. Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * test: skip posix-only fileresolver tests on windows Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix: split contained paths on posix separators on windows - `allContainedPaths` cleaned with the native separator but split on `/`, so a root reached through a symlink never had its ancestors indexed on windows - index assertions in tests now key on the posix path the index actually stores - skip symlink fixture tests and a posix-only test helper on windows Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * chore: revert unrelated go.sum churn and allContainedPaths change - restore `go.sum` and `.make/go.sum` (accidentally populated by a local `-mod=mod` invocation) - revert the `allContainedPaths` separator change: production passes native windows paths there, and splitting them on `/` produces drive-relative ancestors, so skip the posix-only test on windows instead - annotate the remaining `filepath` usages that operate on native paths Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix: search the file tree with posix paths on windows (#5325) The directory and file resolvers key their file tree on posix paths (`/c/some/path`), but `FilesByPath`, `HasPath` and root-anchored `FilesByGlob` searched it with the native path from the chroot context (`C:\some\path`). On windows every lookup silently missed, so anything that resolves files by path found nothing. This is why file digests were empty for `dir:` scans. Requests are now converted to posix before searching the tree. Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
70 lines
2.4 KiB
Go
70 lines
2.4 KiB
Go
package windows
|
|
|
|
import (
|
|
"path"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
const windowsGoOS = "windows"
|
|
const windowsUNCPathPrefix = "\\\\"
|
|
const windowsDriveColon = ":"
|
|
const windowsDrivePathTerminator = ":\\"
|
|
const windowsUNCPathTerminator = "\\"
|
|
|
|
func HostRunningOnWindows() bool {
|
|
return runtime.GOOS == windowsGoOS
|
|
}
|
|
|
|
func ToPosix(windowsPath string) (posixPath string) {
|
|
// volume should be encoded at the start (e.g /c/<path>) where c is the volume
|
|
volumeName := filepath.VolumeName(windowsPath)
|
|
pathWithoutVolume := strings.TrimPrefix(windowsPath, volumeName)
|
|
volumeLetter := strings.ToLower(strings.TrimSuffix(volumeName, ":"))
|
|
|
|
// translate non-escaped backslash to forwardslash
|
|
translatedPath := strings.ReplaceAll(pathWithoutVolume, "\\", "/")
|
|
|
|
// always have `/` as the root... join all components, e.g.:
|
|
// convert: C:\\some\windows\Place
|
|
// into: /c/some/windows/Place
|
|
return path.Clean("/" + strings.Join([]string{volumeLetter, translatedPath}, "/"))
|
|
}
|
|
|
|
func FromPosix(posixPath string) (windowsPath string) {
|
|
// decode the volume (e.g. /c/<path> --> C:\\) - There should always be a volume name.
|
|
// The volume may be a UNC path (e.g. /\\localhost\C$\ --> \\localhost\C$\)
|
|
if !strings.HasPrefix(posixPath, "/") {
|
|
// not a volume-encoded posix path (e.g. relative or already native), so there is nothing to decode
|
|
return posixPath
|
|
}
|
|
pathFields := strings.Split(posixPath, "/")
|
|
if len(pathFields) < 2 {
|
|
// no separator means no volume to decode
|
|
return filepath.Clean(posixPath)
|
|
}
|
|
rootPath := strings.ToUpper(pathFields[1])
|
|
volumeName := AppendRootTerminator(rootPath)
|
|
|
|
// translate non-escaped forward slashes into backslashes
|
|
remainingTranslatedPath := strings.Join(pathFields[2:], "\\")
|
|
|
|
// combine volume name and backslash components
|
|
return filepath.Clean(volumeName + remainingTranslatedPath)
|
|
}
|
|
|
|
func AppendRootTerminator(rootPath string) string {
|
|
// UNC paths start with \\ => \\localhost\
|
|
// Windows drive paths start with a letter and a colon => C:\
|
|
// See https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths
|
|
// This function should not be used on file paths since it is meant for root directory paths!
|
|
if strings.HasSuffix(rootPath, windowsDrivePathTerminator) {
|
|
return rootPath
|
|
}
|
|
if strings.HasPrefix(rootPath, windowsUNCPathPrefix) || strings.HasSuffix(rootPath, windowsDriveColon) {
|
|
return rootPath + windowsUNCPathTerminator
|
|
}
|
|
return rootPath + windowsDrivePathTerminator
|
|
}
|