From 26b037eb6711e77b1292def7a238b984c9432866 Mon Sep 17 00:00:00 2001 From: Simar Date: Mon, 12 Dec 2022 14:19:38 -0800 Subject: [PATCH] sumdb/dirhash: fix a panic when argument is not a directory This patch fixes a case where a path to a non directory can cause DirHash func to panic. Fixes: https://github.com/golang/go/issues/57269 Signed-off-by: Simar --- sumdb/dirhash/hash.go | 10 +++++- sumdb/dirhash/hash_test.go | 68 +++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/sumdb/dirhash/hash.go b/sumdb/dirhash/hash.go index ef5df6f..6c2672e 100644 --- a/sumdb/dirhash/hash.go +++ b/sumdb/dirhash/hash.go @@ -84,7 +84,15 @@ func HashDir(dir, prefix string, hash Hash) (string, error) { func DirFiles(dir, prefix string) ([]string, error) { var files []string dir = filepath.Clean(dir) - err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error { + dirInfo, err := os.Stat(dir) + if err != nil { + return nil, err + } + if !dirInfo.IsDir() { + return nil, fmt.Errorf("invalid directory path") + } + + err = filepath.Walk(dir, func(file string, info os.FileInfo, err error) error { if err != nil { return err } diff --git a/sumdb/dirhash/hash_test.go b/sumdb/dirhash/hash_test.go index ed463c1..5fd00be 100644 --- a/sumdb/dirhash/hash_test.go +++ b/sumdb/dirhash/hash_test.go @@ -105,31 +105,47 @@ func TestHashZip(t *testing.T) { } func TestDirFiles(t *testing.T) { - dir, err := ioutil.TempDir("", "dirfiles-test-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) - if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(filepath.Join(dir, "subdir"), 0777); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(filepath.Join(dir, "subdir", "xyz"), []byte("data for subdir xyz"), 0666); err != nil { - t.Fatal(err) - } - prefix := "foo/bar@v2.3.4" - out, err := DirFiles(dir, prefix) - if err != nil { - t.Fatalf("DirFiles: %v", err) - } - for _, file := range out { - if !strings.HasPrefix(file, prefix) { - t.Errorf("Dir file = %s, want prefix %s", file, prefix) + t.Run("valid directory with files", func(t *testing.T) { + dir, err := ioutil.TempDir("", "dirfiles-test-") + if err != nil { + t.Fatal(err) } - } + defer os.RemoveAll(dir) + if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil { + t.Fatal(err) + } + if err := os.Mkdir(filepath.Join(dir, "subdir"), 0777); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(dir, "subdir", "xyz"), []byte("data for subdir xyz"), 0666); err != nil { + t.Fatal(err) + } + prefix := "foo/bar@v2.3.4" + out, err := DirFiles(dir, prefix) + if err != nil { + t.Fatalf("DirFiles: %v", err) + } + for _, file := range out { + if !strings.HasPrefix(file, prefix) { + t.Errorf("Dir file = %s, want prefix %s", file, prefix) + } + } + }) + + t.Run("invalid directory", func(t *testing.T) { + exePath, err := os.Executable() + if err != nil { + t.Fatalf("DirFiles: %v", err) + } + out, err := DirFiles(exePath, "") + if err == nil { + t.Errorf("DirFiles(...) = %s, want %s", err, "invalid directory path") + } + if len(out) > 0 { + t.Errorf("DirFiles(...) = unexpected files %s", out) + } + }) }