mirror of
https://github.com/anchore/syft.git
synced 2026-02-12 02:26:42 +01:00
unapply base path for resolver inbound requests (#4478)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
e0b61a3ae3
commit
beb70891e5
@ -15,6 +15,7 @@ import (
|
||||
// Note: this only works on a real filesystem, not on a virtual filesystem (such as a stereoscope filetree).
|
||||
type ChrootContext struct {
|
||||
root string
|
||||
rootRelativeToBase string
|
||||
base string
|
||||
cwd string
|
||||
cwdRelativeToRoot string
|
||||
@ -40,8 +41,24 @@ func NewChrootContext(root, base, cwd string) (*ChrootContext, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// we need to track the relative path from root to base (if set) so that request paths can un-apply the base path
|
||||
// changes from any incoming requests.
|
||||
var rootRelativeToBase string
|
||||
if cleanBase != cleanRoot && cleanBase != "" {
|
||||
absRoot := cleanRoot
|
||||
if !filepath.IsAbs(cleanRoot) {
|
||||
absRoot = filepath.Join(cwd, cleanRoot)
|
||||
}
|
||||
|
||||
rootRelativeToBase, err = filepath.Rel(absRoot, cleanBase) // validate that base is within root
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("base path %q is not within root path %q: %w", cleanBase, cleanRoot, err)
|
||||
}
|
||||
}
|
||||
|
||||
chroot := &ChrootContext{
|
||||
root: cleanRoot,
|
||||
rootRelativeToBase: rootRelativeToBase,
|
||||
base: cleanBase,
|
||||
cwd: cwd,
|
||||
}
|
||||
@ -125,8 +142,8 @@ func (r ChrootContext) ToNativePath(chrootPath string) (string, error) {
|
||||
responsePath := chrootPath
|
||||
|
||||
if filepath.IsAbs(responsePath) {
|
||||
// don't allow input to potentially hop above root path
|
||||
responsePath = path.Join(r.root, responsePath)
|
||||
// don't allow input to potentially hop above root path (and still un-apply any base paths)
|
||||
responsePath = path.Join(r.root, r.rootRelativeToBase, responsePath)
|
||||
} else {
|
||||
// ensure we take into account any relative difference between the root path and the CWD for relative requests
|
||||
responsePath = path.Join(r.cwdRelativeToRoot, responsePath)
|
||||
|
||||
@ -452,6 +452,25 @@ func Test_ChrootContext_RequestResponse(t *testing.T) {
|
||||
expectedNativePath: absRelOutsidePath,
|
||||
expectedChrootPath: "to/the/rel-outside.txt",
|
||||
},
|
||||
// base path within root cases...
|
||||
// note: for absolute input paths, rootRelativeToBase is used to resolve the native path
|
||||
// note: for relative input paths, cwdRelativeToRoot is used (base does not affect relative path resolution)
|
||||
{
|
||||
name: "relative root, abs request, with base",
|
||||
root: relative,
|
||||
base: filepath.Join(relative, "path", "to"),
|
||||
input: "/the/file.txt",
|
||||
expectedNativePath: absPathToTheFile,
|
||||
expectedChrootPath: "/the/file.txt", // ToChrootPath trims base prefix without adding separator
|
||||
},
|
||||
{
|
||||
name: "abs root, abs request, with base",
|
||||
root: absolute,
|
||||
base: filepath.Join(absolute, "path", "to"),
|
||||
input: "/the/file.txt",
|
||||
expectedNativePath: absPathToTheFile,
|
||||
expectedChrootPath: "/the/file.txt", // ToChrootPath trims base prefix without adding separator
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
@ -480,6 +499,69 @@ func Test_ChrootContext_RequestResponse(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewChrootContext_BaseValidation(t *testing.T) {
|
||||
testDir, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
relative := filepath.Join("test-fixtures", "req-resp")
|
||||
absolute := filepath.Join(testDir, relative)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
root string
|
||||
base string
|
||||
cwd string
|
||||
expectedRootRelativeToBase string
|
||||
wantErr require.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "base within root",
|
||||
root: absolute,
|
||||
base: filepath.Join(absolute, "path", "to"),
|
||||
cwd: testDir,
|
||||
expectedRootRelativeToBase: filepath.Join("path", "to"),
|
||||
},
|
||||
{
|
||||
name: "base equals root",
|
||||
root: absolute,
|
||||
base: absolute,
|
||||
cwd: testDir,
|
||||
expectedRootRelativeToBase: "",
|
||||
},
|
||||
{
|
||||
name: "empty base",
|
||||
root: absolute,
|
||||
base: "",
|
||||
cwd: testDir,
|
||||
expectedRootRelativeToBase: "",
|
||||
},
|
||||
{
|
||||
name: "relative root with base",
|
||||
root: relative,
|
||||
base: filepath.Join(absolute, "path", "to"),
|
||||
cwd: testDir,
|
||||
expectedRootRelativeToBase: filepath.Join("path", "to"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.wantErr == nil {
|
||||
tt.wantErr = require.NoError
|
||||
}
|
||||
|
||||
ctx, err := NewChrootContext(tt.root, tt.base, tt.cwd)
|
||||
tt.wantErr(t, err)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.expectedRootRelativeToBase, ctx.rootRelativeToBase)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestToNativeGlob(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user