aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2015-05-26 13:49:55 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2015-05-26 22:18:21 +0000
commitfad25c29a1c8c3cffdd18ff8ebff3ead3bdfed1f (patch)
tree61c780aac64a10bbfe6236794c6abd21d672ee17 /src
parentb2f95a167aacc11177d66d1a3235d84a2b1f3538 (diff)
downloadgo-fad25c29a1c8c3cffdd18ff8ebff3ead3bdfed1f.tar.xz
archive/zip: verify number of File bytes read at EOF
Fixes #10957 Change-Id: I75fe25133dfcebd1682a8058b1c354ec894cc997 Reviewed-on: https://go-review.googlesource.com/10384 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Andrew Gerrand <adg@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/archive/zip/reader.go22
-rw-r--r--src/archive/zip/reader_test.go42
2 files changed, 58 insertions, 6 deletions
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index 8136b840d4..10d9d5e5bf 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -146,16 +146,22 @@ func (f *File) Open() (rc io.ReadCloser, err error) {
if f.hasDataDescriptor() {
desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
}
- rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil}
+ rc = &checksumReader{
+ rc: rc,
+ hash: crc32.NewIEEE(),
+ f: f,
+ desr: desr,
+ }
return
}
type checksumReader struct {
- rc io.ReadCloser
- hash hash.Hash32
- f *File
- desr io.Reader // if non-nil, where to read the data descriptor
- err error // sticky error
+ rc io.ReadCloser
+ hash hash.Hash32
+ nread uint64 // number of bytes read so far
+ f *File
+ desr io.Reader // if non-nil, where to read the data descriptor
+ err error // sticky error
}
func (r *checksumReader) Read(b []byte) (n int, err error) {
@@ -164,10 +170,14 @@ func (r *checksumReader) Read(b []byte) (n int, err error) {
}
n, err = r.rc.Read(b)
r.hash.Write(b[:n])
+ r.nread += uint64(n)
if err == nil {
return
}
if err == io.EOF {
+ if r.nread != r.f.UncompressedSize64 {
+ return 0, io.ErrUnexpectedEOF
+ }
if r.desr != nil {
if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
err = err1
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
index 29d0652dcc..6a8cab34cd 100644
--- a/src/archive/zip/reader_test.go
+++ b/src/archive/zip/reader_test.go
@@ -531,3 +531,45 @@ func TestIssue8186(t *testing.T) {
}
}
}
+
+// Verify we return ErrUnexpectedEOF when length is short.
+func TestIssue10957(t *testing.T) {
+ data := []byte("PK\x03\x040000000PK\x01\x0200000" +
+ "0000000000000000000\x00" +
+ "\x00\x00\x00\x00\x00000000000000PK\x01" +
+ "\x020000000000000000000" +
+ "00000\v\x00\x00\x00\x00\x00000000000" +
+ "00000000000000PK\x01\x0200" +
+ "00000000000000000000" +
+ "00\v\x00\x00\x00\x00\x00000000000000" +
+ "00000000000PK\x01\x020000<" +
+ "0\x00\x0000000000000000\v\x00\v" +
+ "\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00000" +
+ "00000000PK\x01\x0200000000" +
+ "0000000000000000\v\x00\x00\x00" +
+ "\x00\x0000PK\x05\x06000000\x05\x000000" +
+ "\v\x00\x00\x00\x00\x00")
+ z, err := NewReader(bytes.NewReader(data), int64(len(data)))
+ if err != nil {
+ if z != nil {
+ panic("non nil z")
+ }
+ return
+ }
+ for i, f := range z.File {
+ r, err := f.Open()
+ if err != nil {
+ continue
+ }
+ if f.UncompressedSize64 < 1e6 {
+ n, err := io.Copy(ioutil.Discard, r)
+ if i == 3 && err != io.ErrUnexpectedEOF {
+ t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err)
+ }
+ if err == nil && uint64(n) != f.UncompressedSize64 {
+ t.Errorf("file %d: bad size: copied=%d; want=%d", i, n, f.UncompressedSize64)
+ }
+ }
+ r.Close()
+ }
+}