]> Cypherpunks repositories - gostls13.git/commitdiff
io/fs, path/filepath: honor SkipDir on second WalkDirFunc error call
authorIan Lance Taylor <iant@golang.org>
Sun, 13 Mar 2022 00:18:23 +0000 (16:18 -0800)
committerIan Lance Taylor <iant@golang.org>
Mon, 28 Mar 2022 22:03:07 +0000 (22:03 +0000)
Fixes #51617

Change-Id: I03e9e575d9bad1481e7e4f051b50a077ba5f2fe0
Reviewed-on: https://go-review.googlesource.com/c/go/+/392154
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
src/io/fs/walk.go
src/io/fs/walk_test.go
src/path/filepath/path.go
src/path/filepath/path_test.go

index 534876bad342051d31bed119f35d45a707ba3a5f..52a51bbd377e5a91c80e9a415024efe6cfc283d6 100644 (file)
@@ -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
                }
        }
index 5e127e71cd96da16f324b6cb90a7e185cc61bc87..04358beb240da6ced6fcea970e21077f08cf298d 100644 (file)
@@ -8,6 +8,8 @@ import (
        . "io/fs"
        "os"
        pathpkg "path"
+       "path/filepath"
+       "reflect"
        "testing"
        "testing/fstest"
 )
@@ -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)
+       }
+}
index b56534deadecfe27ae4bf9afab06fe7182c758b1..0554deb2ffe72fcc3d6e315cca205812f0657a10 100644 (file)
@@ -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
                }
        }
index cfd0c8244d4050dd95977db4d77833659e091fe1..1456ea737a1efa7d6b14f4682e5e18a3451896a5 100644 (file)
@@ -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)
+       }
+}