diff --git a/fstest/fstests/fstests.go b/fstest/fstests/fstests.go index dffeaceb2..2164e912c 100644 --- a/fstest/fstests/fstests.go +++ b/fstest/fstests/fstests.go @@ -12,6 +12,7 @@ import ( "log" "os" "path" + "runtime" "sort" "strings" "testing" @@ -266,20 +267,17 @@ func TestFsListDirRoot(t *testing.T) { // TestFsListSubdir tests List works for a subdirectory func TestFsListSubdir(t *testing.T) { skipIfNotOk(t) - test := func(fileName string) bool { - dir, _ := path.Split(fileName) - dir = dir[:len(dir)-1] - objs, dirs, err := fs.NewLister().Start(remote, dir).GetAll() - if err == fs.ErrorDirNotFound { - return false - } - require.NoError(t, err) - require.Len(t, objs, 1) - assert.Equal(t, fileName, objs[0].Remote()) - require.Len(t, dirs, 0) - return true + fileName := file2.Path + if runtime.GOOS == "windows" { + fileName = file2.WinPath } - assert.True(t, test(file2.Path) || test(file2.WinPath), "normal and alternative lists failed") + dir, _ := path.Split(fileName) + dir = dir[:len(dir)-1] + objs, dirs, err := fs.NewLister().Start(remote, dir).GetAll() + require.NoError(t, err) + require.Len(t, objs, 1) + assert.Equal(t, fileName, objs[0].Remote()) + require.Len(t, dirs, 0) } // TestFsListLevel2 tests List works for 2 levels diff --git a/local/local.go b/local/local.go index c9bb9f2c2..04274bcf8 100644 --- a/local/local.go +++ b/local/local.go @@ -212,7 +212,8 @@ func (f *Fs) list(out fs.ListOpts, remote string, dirpath string, level int) (su // Ignores everything which isn't Storable, eg links etc func (f *Fs) List(out fs.ListOpts, dir string) { defer out.Finished() - root := path.Join(f.root, dir) + dir = filterFragment(f.cleanUtf8(dir)) + root := filepath.Join(f.root, dir) _, err := os.Stat(root) if err != nil { out.SetError(fs.ErrorDirNotFound) @@ -670,11 +671,25 @@ func getDirFile(s string) (string, string) { return dir, file } -func (f *Fs) filterPath(s string) string { +// filterFragment cleans a path fragment which is part of a bigger +// path and not necessarily absolute +func filterFragment(s string) string { + if s == "" { + return s + } s = filepath.Clean(s) if runtime.GOOS == "windows" { s = strings.Replace(s, `/`, `\`, -1) + } + return s +} +// filterPath cleans and makes absolute the path passed in. +// +// On windows it makes the path UNC also. +func (f *Fs) filterPath(s string) string { + s = filterFragment(s) + if runtime.GOOS == "windows" { if !filepath.IsAbs(s) && !strings.HasPrefix(s, "\\") { s2, err := filepath.Abs(s) if err == nil {