forked from TrueCloudLab/rclone
Fix tests failing on Windows.
* ":" is kept when part of a drive. * Create tests. * Fix test framework.
This commit is contained in:
parent
4e952af614
commit
16c9fba5de
3 changed files with 78 additions and 25 deletions
|
@ -36,7 +36,7 @@ var (
|
||||||
file2 = fstest.Item{
|
file2 = fstest.Item{
|
||||||
ModTime: fstest.Time("2001-02-03T04:05:10.123123123Z"),
|
ModTime: fstest.Time("2001-02-03T04:05:10.123123123Z"),
|
||||||
Path: `hello? sausage/êé/Hello, 世界/ " ' @ < > & ?/z.txt`,
|
Path: `hello? sausage/êé/Hello, 世界/ " ' @ < > & ?/z.txt`,
|
||||||
WinPath: `hello_ sausage/êé/Hello, 世界/ _ ' @ _ _ _ _/z.txt`,
|
WinPath: `hello_ sausage/êé/Hello, 世界/ _ ' @ _ _ & _/z.txt`,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -167,30 +167,7 @@ func (f *FsLocal) cleanUtf8(name string) string {
|
||||||
name = string([]rune(name))
|
name = string([]rune(name))
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
var name2 string
|
name = cleanWindowsName(f, name)
|
||||||
if strings.HasPrefix(name, `\\?\`) {
|
|
||||||
name2 = `\\?\`
|
|
||||||
strings.TrimPrefix(name, `\\?\`)
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(name, `//?/`) {
|
|
||||||
name2 = `//?/`
|
|
||||||
strings.TrimPrefix(name, `//?/`)
|
|
||||||
}
|
|
||||||
name2 += strings.Map(func(r rune) rune {
|
|
||||||
switch r {
|
|
||||||
case '<', '>', '"', '|', '?', '*', ':':
|
|
||||||
return '_'
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}, name)
|
|
||||||
|
|
||||||
if name2 != name {
|
|
||||||
if _, ok := f.warned[name]; !ok {
|
|
||||||
fs.Debug(f, "Replacing invalid UTF-8 characters in %q", name)
|
|
||||||
f.warned[name] = struct{}{}
|
|
||||||
}
|
|
||||||
name = name2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
@ -664,6 +641,43 @@ func uncPath(s string) string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cleanWindowsName will clean invalid Windows characters
|
||||||
|
func cleanWindowsName(f *FsLocal, name string) string {
|
||||||
|
original := name
|
||||||
|
var name2 string
|
||||||
|
if strings.HasPrefix(name, `\\?\`) {
|
||||||
|
name2 = `\\?\`
|
||||||
|
name = strings.TrimPrefix(name, `\\?\`)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(name, `//?/`) {
|
||||||
|
name2 = `//?/`
|
||||||
|
name = strings.TrimPrefix(name, `//?/`)
|
||||||
|
}
|
||||||
|
// Colon is allowed as part of a drive name X:\
|
||||||
|
colonAt := strings.Index(name, ":")
|
||||||
|
if colonAt > 0 && colonAt < 3 && len(name) > colonAt+1 {
|
||||||
|
// Copy to name2, which is unfiltered
|
||||||
|
name2 += name[0 : colonAt+1]
|
||||||
|
name = name[colonAt+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
name2 += strings.Map(func(r rune) rune {
|
||||||
|
switch r {
|
||||||
|
case '<', '>', '"', '|', '?', '*', ':':
|
||||||
|
return '_'
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}, name)
|
||||||
|
|
||||||
|
if name2 != original && f != nil {
|
||||||
|
if _, ok := f.warned[name]; !ok {
|
||||||
|
fs.Debug(f, "Replacing invalid characters in %q to %q", name, name2)
|
||||||
|
f.warned[name] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name2
|
||||||
|
}
|
||||||
|
|
||||||
// Check the interfaces are satisfied
|
// Check the interfaces are satisfied
|
||||||
var _ fs.Fs = &FsLocal{}
|
var _ fs.Fs = &FsLocal{}
|
||||||
var _ fs.Purger = &FsLocal{}
|
var _ fs.Purger = &FsLocal{}
|
||||||
|
|
|
@ -50,3 +50,42 @@ func TestUncPaths(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var utf8Tests = [][2]string{
|
||||||
|
[2]string{"ABC", "ABC"},
|
||||||
|
[2]string{string([]byte{0x80}), "<22>"},
|
||||||
|
[2]string{string([]byte{'a', 0x80, 'b'}), "a<>b"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCleanUtf8(t *testing.T) {
|
||||||
|
f := &FsLocal{}
|
||||||
|
f.warned = make(map[string]struct{})
|
||||||
|
for _, test := range utf8Tests {
|
||||||
|
got := f.cleanUtf8(test[0])
|
||||||
|
expect := test[1]
|
||||||
|
if got != expect {
|
||||||
|
t.Fatalf("got %q, expected %q", got, expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Windows character replacements
|
||||||
|
var testsWindows = [][2]string{
|
||||||
|
[2]string{`c:\temp`, `c:\temp`},
|
||||||
|
[2]string{`\\?\UNC\theserver\dir\file.txt`, `\\?\UNC\theserver\dir\file.txt`},
|
||||||
|
[2]string{`//?/UNC/theserver/dir\file.txt`, `//?/UNC/theserver/dir\file.txt`},
|
||||||
|
[2]string{"c:/temp", "c:/temp"},
|
||||||
|
[2]string{"/temp/file.txt", "/temp/file.txt"},
|
||||||
|
[2]string{`!\"#¤%&/()=;:*^?+-`, "!\\_#¤%&/()=;__^_+-"},
|
||||||
|
[2]string{`<>"|?*:&\<>"|?*:&\<>"|?*:&`, "_______&\\_______&\\_______&"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCleanWindows(t *testing.T) {
|
||||||
|
for _, test := range testsWindows {
|
||||||
|
got := cleanWindowsName(nil, test[0])
|
||||||
|
expect := test[1]
|
||||||
|
if got != expect {
|
||||||
|
t.Fatalf("got %q, expected %q", got, expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue