summaryrefslogtreecommitdiff
path: root/src/io
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2021-02-09 13:46:53 -0500
committerRuss Cox <rsc@golang.org>2021-02-11 01:10:28 +0000
commite5b08e6d5cecb646066c0cadddf6300e2a10ffb2 (patch)
tree74c7b56d1c89924544a37c36eb93ddd2fd40b539 /src/io
parented8079096fe2e78d6dcb8002758774dca6d24eee (diff)
downloadgo-git-e5b08e6d5cecb646066c0cadddf6300e2a10ffb2.tar.gz
io/fs: allow backslash in ValidPath, reject in os.DirFS.Open
Rejecting backslash introduces problems with presenting underlying OS file systems that contain names with backslash. Rejecting backslash also does not Windows-proof the syntax, because colon can also be a path separator. And we are not going to reject colon from all names. So don't reject backslash either. There is a similar problem on Windows with names containing slashes, but those are more difficult (though not impossible) to create. Also document and enforce that paths must be UTF-8. Fixes #44166. Change-Id: Iac7a9a268025c1fd31010dbaf3f51e1660c7ae2a Reviewed-on: https://go-review.googlesource.com/c/go/+/290709 TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com> Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/io')
-rw-r--r--src/io/fs/fs.go23
-rw-r--r--src/io/fs/fs_test.go7
2 files changed, 18 insertions, 12 deletions
diff --git a/src/io/fs/fs.go b/src/io/fs/fs.go
index c330f123ad..3d2e2ee2ac 100644
--- a/src/io/fs/fs.go
+++ b/src/io/fs/fs.go
@@ -10,6 +10,7 @@ package fs
import (
"internal/oserror"
"time"
+ "unicode/utf8"
)
// An FS provides access to a hierarchical file system.
@@ -32,15 +33,22 @@ type FS interface {
// ValidPath reports whether the given path name
// is valid for use in a call to Open.
-// Path names passed to open are unrooted, slash-separated
-// sequences of path elements, like “x/y/z”.
-// Path names must not contain a “.” or “..” or empty element,
+//
+// Path names passed to open are UTF-8-encoded,
+// unrooted, slash-separated sequences of path elements, like “x/y/z”.
+// Path names must not contain an element that is “.” or “..” or the empty string,
// except for the special case that the root directory is named “.”.
-// Leading and trailing slashes (like “/x” or “x/”) are not allowed.
+// Paths must not start or end with a slash: “/x” and “x/” are invalid.
//
-// Paths are slash-separated on all systems, even Windows.
-// Backslashes must not appear in path names.
+// Note that paths are slash-separated on all systems, even Windows.
+// Paths containing other characters such as backslash and colon
+// are accepted as valid, but those characters must never be
+// interpreted by an FS implementation as path element separators.
func ValidPath(name string) bool {
+ if !utf8.ValidString(name) {
+ return false
+ }
+
if name == "." {
// special case
return true
@@ -50,9 +58,6 @@ func ValidPath(name string) bool {
for {
i := 0
for i < len(name) && name[i] != '/' {
- if name[i] == '\\' {
- return false
- }
i++
}
elem := name[:i]
diff --git a/src/io/fs/fs_test.go b/src/io/fs/fs_test.go
index 8d395fc0db..aae1a7606f 100644
--- a/src/io/fs/fs_test.go
+++ b/src/io/fs/fs_test.go
@@ -33,9 +33,10 @@ var isValidPathTests = []struct {
{"x/..", false},
{"x/../y", false},
{"x//y", false},
- {`x\`, false},
- {`x\y`, false},
- {`\x`, false},
+ {`x\`, true},
+ {`x\y`, true},
+ {`x:y`, true},
+ {`\x`, true},
}
func TestValidPath(t *testing.T) {