lib/fs: Fix root path handling for Windows (fixes #8778)
Co-authored-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
parent
1103a27337
commit
3adfe2f91f
|
@ -51,8 +51,10 @@ type BasicFilesystem struct {
|
||||||
groupCache *groupCache
|
groupCache *groupCache
|
||||||
}
|
}
|
||||||
|
|
||||||
type userCache = valueCache[string, *user.User]
|
type (
|
||||||
type groupCache = valueCache[string, *user.Group]
|
userCache = valueCache[string, *user.User]
|
||||||
|
groupCache = valueCache[string, *user.Group]
|
||||||
|
)
|
||||||
|
|
||||||
func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem {
|
func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem {
|
||||||
if root == "" {
|
if root == "" {
|
||||||
|
@ -62,11 +64,11 @@ func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem {
|
||||||
// The reason it's done like this:
|
// The reason it's done like this:
|
||||||
// C: -> C:\ -> C:\ (issue that this is trying to fix)
|
// 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
|
// C:\somedir\ -> C:\somedir\ -> C:\somedir
|
||||||
// This way in the tests, we get away without OS specific separators
|
// This way in the tests, we get away without OS specific separators
|
||||||
// in the test configs.
|
// in the test configs.
|
||||||
sep := string(filepath.Separator)
|
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
|
// Attempt tilde expansion; leave unchanged in case of error
|
||||||
if path, err := ExpandTilde(root); err == nil {
|
if path, err := ExpandTilde(root); err == nil {
|
||||||
|
@ -215,7 +217,7 @@ func (f *BasicFilesystem) DirNames(name string) ([]string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fd, err := os.OpenFile(name, OptReadOnly, 0777)
|
fd, err := os.OpenFile(name, OptReadOnly, 0o777)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,29 +12,46 @@ package fs
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWindowsPaths(t *testing.T) {
|
func TestWindowsPaths(t *testing.T) {
|
||||||
testCases := []struct {
|
type testCase struct {
|
||||||
input string
|
input string
|
||||||
expectedRoot string
|
expectedRoot string
|
||||||
expectedURI string
|
expectedURI string
|
||||||
}{
|
}
|
||||||
|
testCases := []testCase{
|
||||||
|
{`e:`, `\\?\e:\`, `e:\`},
|
||||||
{`e:\`, `\\?\e:\`, `e:\`},
|
{`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`},
|
{`\\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)
|
fs := newBasicFilesystem(testCase.input)
|
||||||
if fs.root != testCase.expectedRoot {
|
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 {
|
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) {
|
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)
|
fs, dir := setup(t)
|
||||||
relativePath := "folder_with_icon"
|
relativePath := "folder_with_icon"
|
||||||
|
|
Loading…
Reference in New Issue