archive/zip: don't read directories containing file data

Fixes #54801

Change-Id: I3d03516792975ddb09835b2621c57e12e7cbad35
GitHub-Last-Rev: 4faa7e14dc
GitHub-Pull-Request: golang/go#56714
Reviewed-on: https://go-review.googlesource.com/c/go/+/449955
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
This commit is contained in:
Alexander Yastrebov 2022-11-11 23:23:19 +00:00 committed by Gopher Robot
parent c55d184151
commit 40bdcbb483
2 changed files with 49 additions and 0 deletions

View File

@ -197,6 +197,13 @@ func (f *File) Open() (io.ReadCloser, error) {
if err != nil {
return nil, err
}
if strings.HasSuffix(f.Name, "/") {
if f.CompressedSize64 != 0 || f.hasDataDescriptor() {
return &dirReader{ErrFormat}, nil
} else {
return &dirReader{io.EOF}, nil
}
}
size := int64(f.CompressedSize64)
r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
dcomp := f.zip.decompressor(f.Method)
@ -228,6 +235,18 @@ func (f *File) OpenRaw() (io.Reader, error) {
return r, nil
}
type dirReader struct {
err error
}
func (r *dirReader) Read([]byte) (int, error) {
return 0, r.err
}
func (r *dirReader) Close() error {
return nil
}
type checksumReader struct {
rc io.ReadCloser
hash hash.Hash32

View File

@ -1554,3 +1554,33 @@ func TestUnderSize(t *testing.T) {
})
}
}
func TestIssue54801(t *testing.T) {
for _, input := range []string{"testdata/readme.zip", "testdata/dd.zip"} {
z, err := OpenReader(input)
if err != nil {
t.Fatal(err)
}
defer z.Close()
for _, f := range z.File {
// Make file a directory
f.Name += "/"
t.Run(f.Name, func(t *testing.T) {
t.Logf("CompressedSize64: %d, Flags: %#x", f.CompressedSize64, f.Flags)
rd, err := f.Open()
if err != nil {
t.Fatal(err)
}
defer rd.Close()
n, got := io.Copy(io.Discard, rd)
if n != 0 || got != ErrFormat {
t.Fatalf("Error mismatch, got: %d, %v, want: %v", n, got, ErrFormat)
}
})
}
}
}