fix(s3): use path.Dir instead of filepath.Dir in directoryDiff (#4950)

This commit is contained in:
Milos Gajdos authored and GitHub committed 2026-09-21 16:05:54 +01:00
commit 34c2599fa3
2 files changed
+56 -2

No files matched your search

+7 -2
View File
@@ -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
}
+49
View File
@@ -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)