diff options
author | Ross Smith II <ross@smithii.com> | 2023-05-03 10:51:24 +0200 |
---|---|---|
committer | Jakob Borg <jakob@kastelo.net> | 2023-05-09 10:01:57 +0000 |
commit | 3adfe2f91f6c3e170f70d04c76b6bcbcee31db26 (patch) | |
tree | b27fd1098da1b69ff5778c2605829516e212e106 | |
parent | 1103a27337ba97ba17e7ec77bd002fb4061c5d24 (diff) |
lib/fs: Fix root path handling for Windows (fixes #8778)
Co-authored-by: Jakob Borg <jakob@kastelo.net>
-rw-r--r-- | lib/fs/basicfs.go | 12 | ||||
-rw-r--r-- | lib/fs/basicfs_windows_test.go | 29 |
2 files changed, 30 insertions, 11 deletions
diff --git a/lib/fs/basicfs.go b/lib/fs/basicfs.go index 8ae1325923..51e598ed2d 100644 --- a/lib/fs/basicfs.go +++ b/lib/fs/basicfs.go @@ -51,8 +51,10 @@ type BasicFilesystem struct { groupCache *groupCache } -type userCache = valueCache[string, *user.User] -type groupCache = valueCache[string, *user.Group] +type ( + userCache = valueCache[string, *user.User] + groupCache = valueCache[string, *user.Group] +) func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem { if root == "" { @@ -62,11 +64,11 @@ func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem { // The reason it's done like this: // C: -> C:\ -> C:\ (issue that this is trying to fix) // C:\somedir -> C:\somedir\ -> C:\somedir - // C:\somedir\ -> C:\somedir\\ -> C:\somedir + // C:\somedir\ -> C:\somedir\ -> C:\somedir // This way in the tests, we get away without OS specific separators // in the test configs. sep := string(filepath.Separator) - root = filepath.Dir(root + sep) + root = filepath.Clean(filepath.Dir(root + sep)) // Attempt tilde expansion; leave unchanged in case of error if path, err := ExpandTilde(root); err == nil { @@ -215,7 +217,7 @@ func (f *BasicFilesystem) DirNames(name string) ([]string, error) { if err != nil { return nil, err } - fd, err := os.OpenFile(name, OptReadOnly, 0777) + fd, err := os.OpenFile(name, OptReadOnly, 0o777) if err != nil { return nil, err } diff --git a/lib/fs/basicfs_windows_test.go b/lib/fs/basicfs_windows_test.go index 5526dd2207..d3ead2421e 100644 --- a/lib/fs/basicfs_windows_test.go +++ b/lib/fs/basicfs_windows_test.go @@ -12,29 +12,46 @@ package fs import ( "os" "path/filepath" + "runtime" "strings" "syscall" "testing" ) func TestWindowsPaths(t *testing.T) { - testCases := []struct { + type testCase struct { input string expectedRoot string expectedURI string - }{ + } + testCases := []testCase{ + {`e:`, `\\?\e:\`, `e:\`}, {`e:\`, `\\?\e:\`, `e:\`}, + {`e:\\`, `\\?\e:\`, `e:\`}, + {`\\?\e:`, `\\?\e:\`, `e:\`}, {`\\?\e:\`, `\\?\e:\`, `e:\`}, + {`\\?\e:\\`, `\\?\e:\`, `e:\`}, + {`e:\x`, `\\?\e:\x`, `e:\x`}, + {`e:\x\`, `\\?\e:\x`, `e:\x`}, + {`e:\x\\`, `\\?\e:\x`, `e:\x`}, {`\\192.0.2.22\network\share`, `\\192.0.2.22\network\share`, `\\192.0.2.22\network\share`}, } - for _, testCase := range testCases { + if runtime.Version() >= "go1.20" { + testCases = append(testCases, + testCase{`\\.\e:`, `\\.\e:\`, `e:\`}, + testCase{`\\.\e:\`, `\\.\e:\`, `e:\`}, + testCase{`\\.\e:\\`, `\\.\e:\`, `e:\`}, + ) + } + + for i, testCase := range testCases { fs := newBasicFilesystem(testCase.input) if fs.root != testCase.expectedRoot { - t.Errorf("root %q != %q", fs.root, testCase.expectedRoot) + t.Errorf("test %d: root: expected `%s`, got `%s`", i, testCase.expectedRoot, fs.root) } if fs.URI() != testCase.expectedURI { - t.Errorf("uri %q != %q", fs.URI(), testCase.expectedURI) + t.Errorf("test %d: uri: expected `%s`, got `%s`", i, testCase.expectedURI, fs.URI()) } } @@ -195,7 +212,7 @@ func TestGetFinalPath(t *testing.T) { } func TestRemoveWindowsDirIcon(t *testing.T) { - //Try to delete a folder with a custom icon with os.Remove (simulated by the readonly file attribute) + // Try to delete a folder with a custom icon with os.Remove (simulated by the readonly file attribute) fs, dir := setup(t) relativePath := "folder_with_icon" |