commit e40c9a2d59a1d779c89d5cf7e337d7fb10009199
parent 0604313fa77458c4d504f82453a491469a2ccc9b
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sun, 7 Jan 2024 13:48:11 +0900
add client.cleanPath and its test
Diffstat:
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/client/fs.go b/client/fs.go
@@ -45,6 +45,22 @@ func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error)
return f, nil
}
+// CleanPath cleans name.
+// It first call path.Clean(name) and then
+// delete trailing ".." elements.
+func cleanPath(name string) string {
+ name = path.Clean(name)
+ for strings.HasPrefix(name, "../") {
+ name = name[3:]
+ }
+ if len(name) == 0 || name == "/" || name == ".." {
+ name = "."
+ } else if name[0] == '/' {
+ name = name[1:]
+ }
+ return name
+}
+
// walkFile walks the file system to the file named name and
// returns the corresponding file.
// returned file is not open.
@@ -55,7 +71,7 @@ func (fsys *FS) walkFile(name string) (*File, error) {
}
var wname []string
if name != "." {
- wname = strings.Split(path.Clean(name), "/")
+ wname = strings.Split(cleanPath(name), "/")
}
tag, err := fsys.tPool.add()
if err != nil {
diff --git a/client/fs2_test.go b/client/fs2_test.go
@@ -10,6 +10,28 @@ import (
"git.mtkn.jp/lib9p"
)
+func TestCleanPath(t *testing.T) {
+ tests := []struct{
+ name string
+ want string
+ }{
+ {"../../../unko", "unko"},
+ {"..", "."},
+ {".", "."},
+ {"/", "."},
+ {"a", "a"},
+ {"a/b/", "a/b"},
+ {".../", "..."},
+ {"../a/../b/../c/../d/", "d"},
+ }
+ for _, test := range tests {
+ got := cleanPath(test.name)
+ if got != test.want {
+ t.Errorf("cleanPath(%q) = %q, want: %q", test.name, got, test.want)
+ }
+ }
+}
+
// TestOpenFile checks if *FS.OpenFile opens every file in testfs without error
// other than permission error and
// every opened file is the same as that of testfs by comparing their lib9p.Stat.