Skip to content

Commit

Permalink
io/fs, path/filepath: honor SkipDir on second WalkDirFunc error call
Browse files Browse the repository at this point in the history
Fixes golang#51617

Change-Id: I03e9e575d9bad1481e7e4f051b50a077ba5f2fe0
Reviewed-on: https://go-review.googlesource.com/c/go/+/392154
Trust: Ian Lance Taylor <[email protected]>
Run-TryBot: Ian Lance Taylor <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Emmanuel Odeke <[email protected]>
  • Loading branch information
ianlancetaylor committed Mar 28, 2022
1 parent 3c7f9b8 commit 460fd63
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/io/fs/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ func walkDir(fsys FS, name string, d DirEntry, walkDirFn WalkDirFunc) error {
// Second call, to report ReadDir error.
err = walkDirFn(name, d, err)
if err != nil {
if err == SkipDir && d.IsDir() {
err = nil
}
return err
}
}
Expand Down
33 changes: 33 additions & 0 deletions src/io/fs/walk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
. "io/fs"
"os"
pathpkg "path"
"path/filepath"
"reflect"
"testing"
"testing/fstest"
)
Expand Down Expand Up @@ -122,3 +124,34 @@ func TestWalkDir(t *testing.T) {
}
checkMarks(t, true)
}

func TestIssue51617(t *testing.T) {
dir := t.TempDir()
for _, sub := range []string{"a", filepath.Join("a", "bad"), filepath.Join("a", "next")} {
if err := os.Mkdir(filepath.Join(dir, sub), 0755); err != nil {
t.Fatal(err)
}
}
bad := filepath.Join(dir, "a", "bad")
if err := os.Chmod(bad, 0); err != nil {
t.Fatal(err)
}
defer os.Chmod(bad, 0700) // avoid errors on cleanup
var saw []string
err := WalkDir(os.DirFS(dir), ".", func(path string, d DirEntry, err error) error {
if err != nil {
return filepath.SkipDir
}
if d.IsDir() {
saw = append(saw, path)
}
return nil
})
if err != nil {
t.Fatal(err)
}
want := []string{".", "a", "a/bad", "a/next"}
if !reflect.DeepEqual(saw, want) {
t.Errorf("got directories %v, want %v", saw, want)
}
}
3 changes: 3 additions & 0 deletions src/path/filepath/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ func walkDir(path string, d fs.DirEntry, walkDirFn fs.WalkDirFunc) error {
// Second call, to report ReadDir error.
err = walkDirFn(path, d, err)
if err != nil {
if err == SkipDir && d.IsDir() {
err = nil
}
return err
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/path/filepath/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1526,3 +1526,38 @@ func TestEvalSymlinksAboveRootChdir(t *testing.T) {
t.Logf("EvalSymlinks(%q) = %q", check, resolved)
}
}

func TestIssue51617(t *testing.T) {
dir := t.TempDir()
for _, sub := range []string{"a", filepath.Join("a", "bad"), filepath.Join("a", "next")} {
if err := os.Mkdir(filepath.Join(dir, sub), 0755); err != nil {
t.Fatal(err)
}
}
bad := filepath.Join(dir, "a", "bad")
if err := os.Chmod(bad, 0); err != nil {
t.Fatal(err)
}
defer os.Chmod(bad, 0700) // avoid errors on cleanup
var saw []string
err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return filepath.SkipDir
}
if d.IsDir() {
rel, err := filepath.Rel(dir, path)
if err != nil {
t.Fatal(err)
}
saw = append(saw, rel)
}
return nil
})
if err != nil {
t.Fatal(err)
}
want := []string{".", "a", filepath.Join("a", "bad"), filepath.Join("a", "next")}
if !reflect.DeepEqual(saw, want) {
t.Errorf("got directories %v, want %v", saw, want)
}
}

0 comments on commit 460fd63

Please sign in to comment.