archive/zip: error on ReadDir if there are invalid file names

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>
This commit is contained in:
Sean Liao 2025-03-10 22:10:58 +00:00 committed by Gopher Robot
parent 817218a26c
commit 908af6529c
2 changed files with 51 additions and 0 deletions

View 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
}

View 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")