Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,21 @@ func (m *Fs) path(p string) string {
return PathJoin(cwd, p)
}

// An unrestricted medium passes an absolute path through as it
// stands — only a relative one was rewritten above. No "/" prefix
// here: prefixing was a no-op for a POSIX absolute path ("//x"
// cleans to "/x") but corrupted a Windows drive-letter one —
// filepath.Clean(`/C:\models`) is `\C:\models`, a path no Win32
// open resolves, which silently emptied every List/Read walk on
// an absolute path there.
if root == "/" {
return CleanPath(p, string(PathSeparator))
}

// Use a leading slash to resolve all .. and . internally
// before joining with the root. This is a standard way to sandbox paths.
clean := CleanPath("/"+p, string(PathSeparator))

// If root is "/", allow absolute paths through
if root == "/" {
return clean
}

// Strip leading "/" so Join works correctly with root
return PathJoin(root, clean[1:])
}
Expand Down
9 changes: 9 additions & 0 deletions fs_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ func TestFs_Fs_path_Ugly(t *T) {
fsys := (&Fs{}).New("/")

AssertEqual(t, PathJoin(cwd.Value.(string), "relative.txt"), fsys.path("relative.txt"))

// An absolute path on an unrestricted medium comes back as itself —
// no "/" prefix bolted on first. The prefix was invisible on POSIX
// ("//x" cleans to "/x") and turned a Windows drive-letter path into
// `\C:\models`, which no Win32 open resolves. PathIsAbs recognises
// the drive-letter form on every platform, so this pins the contract
// everywhere, not just on a windows runner.
AssertEqual(t, `C:\models\gemma`, fsys.path(`C:\models\gemma`))
AssertEqual(t, CleanPath("/tmp//x/../y", string(PathSeparator)), fsys.path("/tmp//x/../y"))
}
func TestFs_Fs_validatePath_Good(t *T) {
root := t.TempDir()
Expand Down
Loading