mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-03 02:32:35 +01:00
filer: reuse IsEqualOrUnder for the rename subdirectory check (#12338)
* filer: test the rename subdirectory check through CanRename Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * filer: reuse IsEqualOrUnder for the rename subdirectory check A trailing slash on the old name made the source path end in a slash, so a child of the source was no longer seen as under it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d650abe0e7
commit
690aabda0e
2 files changed
+30
-22
No files matched your search
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
func (f *Filer) CanRename(ctx context.Context, source, target util.FullPath, oldName string) error {
|
||||
sourcePath := source.Child(oldName)
|
||||
if movesIntoItself(sourcePath, target) {
|
||||
if util.IsEqualOrUnder(string(target), string(sourcePath)) {
|
||||
return fmt.Errorf("mv: can not move directory to a subdirectory of itself")
|
||||
}
|
||||
|
||||
@@ -33,13 +33,6 @@ func (f *Filer) CanRename(ctx context.Context, source, target util.FullPath, old
|
||||
return nil
|
||||
}
|
||||
|
||||
// movesIntoItself reports whether target, the new parent directory, is
|
||||
// sourcePath or lies under it. A sibling that only shares a name prefix,
|
||||
// such as /a.d for /a, does not.
|
||||
func movesIntoItself(sourcePath, target util.FullPath) bool {
|
||||
return target == sourcePath || target.IsUnder(sourcePath)
|
||||
}
|
||||
|
||||
func (f *Filer) DetectBucket(source util.FullPath) (bucket string) {
|
||||
if strings.HasPrefix(string(source), f.DirBucketsPath+"/") {
|
||||
bucketAndObjectKey := string(source)[len(f.DirBucketsPath)+1:]
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package filer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
@@ -30,25 +33,37 @@ func TestDetectBucket(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMovesIntoItself(t *testing.T) {
|
||||
func TestCanRenameIntoItself(t *testing.T) {
|
||||
f, store := newTestFilerWithStubStore(t)
|
||||
f.DirBucketsPath = "/buckets"
|
||||
if err := store.InsertEntry(context.Background(), &Entry{FullPath: "/dir/a", Attr: Attr{Mode: os.ModeDir}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
sourcePath string
|
||||
target string
|
||||
want bool
|
||||
name string
|
||||
oldName string
|
||||
target string
|
||||
reject bool
|
||||
}{
|
||||
{"into itself", "/dir/a", "/dir/a", true},
|
||||
{"into a child", "/dir/a", "/dir/a/b", true},
|
||||
{"into a deeper descendant", "/dir/a", "/dir/a/b/c", true},
|
||||
{"into a sibling sharing the name prefix", "/dir/a", "/dir/a.d", false},
|
||||
{"into a descendant of that sibling", "/dir/a", "/dir/ab/c", false},
|
||||
{"into the parent", "/dir/a", "/dir", false},
|
||||
{"into an unrelated directory", "/dir/a", "/other", false},
|
||||
{"into itself", "a", "/dir/a", true},
|
||||
{"into a child", "a", "/dir/a/b", true},
|
||||
{"into a deeper descendant", "a", "/dir/a/b/c", true},
|
||||
{"into a child with a trailing slash", "a", "/dir/a/b/", true},
|
||||
{"old name with a trailing slash into a child", "a/", "/dir/a/b", true},
|
||||
{"into a sibling sharing the name prefix", "a", "/dir/a.d", false},
|
||||
{"into a descendant of that sibling", "a", "/dir/ab/c", false},
|
||||
{"into the parent", "a", "/dir", false},
|
||||
{"into an unrelated directory", "a", "/other", false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := movesIntoItself(util.FullPath(tt.sourcePath), util.FullPath(tt.target)); got != tt.want {
|
||||
t.Errorf("movesIntoItself(%q, %q) = %v, want %v", tt.sourcePath, tt.target, got, tt.want)
|
||||
err := f.CanRename(context.Background(), "/dir", util.FullPath(tt.target), tt.oldName)
|
||||
rejected := err != nil && strings.Contains(err.Error(), "subdirectory of itself")
|
||||
if rejected != tt.reject {
|
||||
t.Errorf("CanRename(/dir, %q, %q) = %v, want rejected=%v", tt.target, tt.oldName, err, tt.reject)
|
||||
}
|
||||
if !tt.reject && err != nil {
|
||||
t.Errorf("CanRename(/dir, %q, %q) = %v, want nil", tt.target, tt.oldName, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user