mirror of
https://github.com/distribution/distribution.git
synced 2026-10-28 10:15:27 +08:00
fix(s3): use path.Dir instead of filepath.Dir in directoryDiff (#4950)
This commit is contained in:
2 files changed
+56
-2
No files matched your search
@@ -21,7 +21,7 @@ import (
|
||||
"math"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -1230,6 +1230,11 @@ func (d *driver) doWalk(parentCtx context.Context, objectCount *int64, from, sta
|
||||
//
|
||||
// directoryDiff("/", "/path/to/folder/folder/file")
|
||||
// // => [ "/path", "/path/to", "/path/to/folder", "/path/to/folder/folder" ]
|
||||
//
|
||||
// prev and current are S3 object keys, which always use "/" as a separator
|
||||
// regardless of host OS, so this must use path.Dir rather than filepath.Dir:
|
||||
// on Windows, filepath.Dir converges to "\" instead of "/", so the loop's
|
||||
// "/" exit condition never fires and it never terminates.
|
||||
func directoryDiff(prev, current string) []string {
|
||||
var paths []string
|
||||
|
||||
@@ -1239,7 +1244,7 @@ func directoryDiff(prev, current string) []string {
|
||||
|
||||
parent := current
|
||||
for {
|
||||
parent = filepath.Dir(parent)
|
||||
parent = path.Dir(parent)
|
||||
if parent == "/" || parent == prev || strings.HasPrefix(prev+"/", parent+"/") {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -341,6 +341,55 @@ func TestIsSubpath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirectoryDiff(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
prev string
|
||||
current string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "immediate child",
|
||||
prev: "/path/to/folder",
|
||||
current: "/path/to/folder/folder/file",
|
||||
expected: []string{"/path/to/folder/folder"},
|
||||
},
|
||||
{
|
||||
name: "sibling folder",
|
||||
prev: "/path/to/folder/folder1",
|
||||
current: "/path/to/folder/folder2/file",
|
||||
expected: []string{"/path/to/folder/folder2"},
|
||||
},
|
||||
{
|
||||
name: "sibling folder, prev is a file",
|
||||
prev: "/path/to/folder/folder1/file",
|
||||
current: "/path/to/folder/folder2/file",
|
||||
expected: []string{"/path/to/folder/folder2"},
|
||||
},
|
||||
{
|
||||
name: "multiple missing directories",
|
||||
prev: "/path/to/folder/folder1/file",
|
||||
current: "/path/to/folder/folder2/folder1/file",
|
||||
expected: []string{"/path/to/folder/folder2", "/path/to/folder/folder2/folder1"},
|
||||
},
|
||||
{
|
||||
name: "from root, deeply nested",
|
||||
prev: "/",
|
||||
current: "/path/to/folder/folder/file",
|
||||
expected: []string{"/path", "/path/to", "/path/to/folder", "/path/to/folder/folder"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := directoryDiff(tt.prev, tt.current)
|
||||
if !slices.Equal(actual, tt.expected) {
|
||||
t.Fatalf("directoryDiff(%q, %q) = %v, want %v", tt.prev, tt.current, actual, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyRootList(t *testing.T) {
|
||||
skipCheck(t)
|
||||
|
||||
|
||||
Reference in new issue
Block a user