From f62e7b5b30be8357e53fe0134baafe25cf552238 Mon Sep 17 00:00:00 2001 From: nielash Date: Sun, 24 Mar 2024 06:01:23 -0400 Subject: [PATCH] memory: fix incorrect list entries when rooted at subdirectory Before this change, List would return incorrect directory paths (relative to the wrong root) if the Fs root pointed to a subdirectory. For example, listing dir "a/b/c/d" of remote :memory: would work correctly, but listing dir "c/d" of remote :memory:a/b would not, and would result in "Entry doesn't belong in directory %q (contains subdir)" errors. This change fixes the issue and adds a test to detect any other backends that might have the same issue. --- backend/memory/memory.go | 2 +- fstest/fstests/fstests.go | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/backend/memory/memory.go b/backend/memory/memory.go index 608f42292..48cc9678b 100644 --- a/backend/memory/memory.go +++ b/backend/memory/memory.go @@ -296,7 +296,7 @@ func (f *Fs) list(ctx context.Context, bucket, directory, prefix string, addBuck slash := strings.IndexRune(localPath, '/') if slash >= 0 { // send a directory if have a slash - dir := directory + localPath[:slash] + dir := strings.TrimPrefix(directory, f.rootDirectory+"/") + localPath[:slash] if addBucket { dir = path.Join(bucket, dir) } diff --git a/fstest/fstests/fstests.go b/fstest/fstests/fstests.go index 72527a1e4..80be1cbe0 100644 --- a/fstest/fstests/fstests.go +++ b/fstest/fstests/fstests.go @@ -24,6 +24,7 @@ import ( "time" "github.com/rclone/rclone/fs" + "github.com/rclone/rclone/fs/cache" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/fspath" @@ -1209,6 +1210,28 @@ func Run(t *testing.T, opt *Opt) { }, fs.GetModifyWindow(ctx, f)) }) + // TestFsListRootedSubdir tests putting and listing with an Fs that is rooted at a subdirectory 2 levels down + TestFsListRootedSubdir := func(t *testing.T) { + skipIfNotOk(t) + newF, err := cache.Get(ctx, subRemoteName+"/hello? sausage/êé") + assert.NoError(t, err) + nestedFile := fstest.Item{ + ModTime: fstest.Time("2001-02-03T04:05:06.499999999Z"), + Path: "a/b/c/d/e.txt", + } + _, _ = testPut(ctx, t, newF, &nestedFile) + + objs, dirs, err := walk.GetAll(ctx, newF, "", true, 10) + require.NoError(t, err) + assert.Equal(t, []string{`Hello, 世界/ " ' @ < > & ? + ≠/z.txt`, nestedFile.Path}, objsToNames(objs)) + assert.Equal(t, []string{`Hello, 世界`, `Hello, 世界/ " ' @ < > & ? + ≠`, "a", "a/b", "a/b/c", "a/b/c/d"}, dirsToNames(dirs)) + + // cleanup + err = operations.Purge(ctx, newF, "a") + require.NoError(t, err) + } + t.Run("FsListRootedSubdir", TestFsListRootedSubdir) + // TestFsCopy tests Copy t.Run("FsCopy", func(t *testing.T) { skipIfNotOk(t)