mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
b2f95a167a
commit
fad25c29a1
2 changed files with 58 additions and 6 deletions
|
|
@ -146,16 +146,22 @@ func (f *File) Open() (rc io.ReadCloser, err error) {
|
||||||
if f.hasDataDescriptor() {
|
if f.hasDataDescriptor() {
|
||||||
desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type checksumReader struct {
|
type checksumReader struct {
|
||||||
rc io.ReadCloser
|
rc io.ReadCloser
|
||||||
hash hash.Hash32
|
hash hash.Hash32
|
||||||
f *File
|
nread uint64 // number of bytes read so far
|
||||||
desr io.Reader // if non-nil, where to read the data descriptor
|
f *File
|
||||||
err error // sticky error
|
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) {
|
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)
|
n, err = r.rc.Read(b)
|
||||||
r.hash.Write(b[:n])
|
r.hash.Write(b[:n])
|
||||||
|
r.nread += uint64(n)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
|
if r.nread != r.f.UncompressedSize64 {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
if r.desr != nil {
|
if r.desr != nil {
|
||||||
if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
|
if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
|
||||||
err = err1
|
err = err1
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue