diff options
| author | Damien Neil <dneil@google.com> | 2022-11-09 17:49:44 -0800 |
|---|---|---|
| committer | Damien Neil <dneil@google.com> | 2022-11-16 23:17:58 +0000 |
| commit | 6d0bf438e302afcb0db5422ea2da59d1995e08c1 (patch) | |
| tree | b931b814d4a959903ea32c37ec69d92fcb0ca7c5 /src/path/filepath/path.go | |
| parent | fd59c6cf8cb600f2911864948303016581abf016 (diff) | |
| download | go-6d0bf438e302afcb0db5422ea2da59d1995e08c1.tar.xz | |
path/filepath: add IsLocal
IsLocal reports whether a path lexically refers to a location
contained within the directory in which it is evaluated.
It identifies paths that are absolute, escape a directory
with ".." elements, and (on Windows) paths that reference
reserved device names.
For #56219.
Change-Id: I35edfa3ce77b40b8e66f1fc8e0ff73cfd06f2313
Reviewed-on: https://go-review.googlesource.com/c/go/+/449239
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Joedian Reid <joedian@golang.org>
Diffstat (limited to 'src/path/filepath/path.go')
| -rw-r--r-- | src/path/filepath/path.go | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go index c5c54fc9a5..a6578cbb72 100644 --- a/src/path/filepath/path.go +++ b/src/path/filepath/path.go @@ -172,6 +172,46 @@ func Clean(path string) string { return FromSlash(out.string()) } +// IsLocal reports whether path, using lexical analysis only, has all of these properties: +// +// - is within the subtree rooted at the directory in which path is evaluated +// - is not an absolute path +// - is not empty +// - on Windows, is not a reserved name such as "NUL" +// +// If IsLocal(path) returns true, then +// Join(base, path) will always produce a path contained within base and +// Clean(path) will always produce an unrooted path with no ".." path elements. +// +// IsLocal is a purely lexical operation. +// In particular, it does not account for the effect of any symbolic links +// that may exist in the filesystem. +func IsLocal(path string) bool { + return isLocal(path) +} + +func unixIsLocal(path string) bool { + if IsAbs(path) || path == "" { + return false + } + hasDots := false + for p := path; p != ""; { + var part string + part, p, _ = strings.Cut(p, "/") + if part == "." || part == ".." { + hasDots = true + break + } + } + if hasDots { + path = Clean(path) + } + if path == ".." || strings.HasPrefix(path, "../") { + return false + } + return true +} + // ToSlash returns the result of replacing each separator character // in path with a slash ('/') character. Multiple separators are // replaced by multiple slashes. |
