]> Cypherpunks repositories - gostls13.git/commitdiff
archive/zip: error on ReadDir if there are invalid file names
authorSean Liao <sean@liao.dev>
Mon, 10 Mar 2025 22:10:58 +0000 (22:10 +0000)
committerGopher Robot <gobot@golang.org>
Tue, 11 Mar 2025 22:19:38 +0000 (15:19 -0700)
Fixes #50179

Change-Id: I616a6d1279d025e345d2daa6d44b687c8a2d09e1
Reviewed-on: https://go-review.googlesource.com/c/go/+/656495
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/archive/zip/reader.go
src/archive/zip/reader_test.go

index 963526db1109887d78ace1a64a8cb17c1ecdf82b..6b57f767fc849d7cd47428fb566f5a922a874aab 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bufio"
        "encoding/binary"
        "errors"
+       "fmt"
        "hash"
        "hash/crc32"
        "internal/godebug"
@@ -988,6 +989,12 @@ func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
                s, err := d.files[d.offset+i].stat()
                if err != nil {
                        return nil, err
+               } else if s.Name() == "." || !fs.ValidPath(s.Name()) {
+                       return nil, &fs.PathError{
+                               Op:   "readdir",
+                               Path: d.e.name,
+                               Err:  fmt.Errorf("invalid file name: %v", d.files[d.offset+i].name),
+                       }
                }
                list[i] = s
        }
index bfa35c992a924c0717e473c57b9c9f8d6f2d6500..410b2d037e44d5671fdb6b35de9a3e1fa61cfbc8 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bytes"
        "encoding/binary"
        "encoding/hex"
+       "errors"
        "internal/obscuretestdata"
        "io"
        "io/fs"
@@ -1281,6 +1282,49 @@ func TestFSWalk(t *testing.T) {
        }
 }
 
+func TestFSWalkBadFile(t *testing.T) {
+       t.Parallel()
+
+       var buf bytes.Buffer
+       zw := NewWriter(&buf)
+       hdr := &FileHeader{Name: "."}
+       hdr.SetMode(fs.ModeDir | 0o755)
+       w, err := zw.CreateHeader(hdr)
+       if err != nil {
+               t.Fatalf("create zip header: %v", err)
+       }
+       _, err = w.Write([]byte("some data"))
+       if err != nil {
+               t.Fatalf("write zip contents: %v", err)
+
+       }
+       err = zw.Close()
+       if err != nil {
+               t.Fatalf("close zip writer: %v", err)
+
+       }
+
+       zr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+       if err != nil {
+               t.Fatalf("create zip reader: %v", err)
+
+       }
+       var count int
+       var errRepeat = errors.New("repeated call to path")
+       err = fs.WalkDir(zr, ".", func(p string, d fs.DirEntry, err error) error {
+               count++
+               if count > 2 { // once for directory read, once for the error
+                       return errRepeat
+               }
+               return err
+       })
+       if err == nil {
+               t.Fatalf("expected error from invalid file name")
+       } else if errors.Is(err, errRepeat) {
+               t.Fatal(err)
+       }
+}
+
 func TestFSModTime(t *testing.T) {
        t.Parallel()
        z, err := OpenReader("testdata/subdir.zip")