From: Nigel Tao Date: Thu, 23 Apr 2015 04:14:31 +0000 (+1000) Subject: image/png: don't silently swallow io.ReadFull's io.EOF error when it X-Git-Tag: go1.5beta1~944 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ba8fa0e1a90b01727c9aa6bb23d6c3981cee9b4e;p=gostls13.git image/png: don't silently swallow io.ReadFull's io.EOF error when it lands exactly on an IDAT row boundary. Fixes #10493 Change-Id: I12be7c5bdcde7032e17ed1d4400db5f17c72bc87 Reviewed-on: https://go-review.googlesource.com/9270 Reviewed-by: Rob Pike --- diff --git a/src/image/png/reader.go b/src/image/png/reader.go index dae7a7db37..33218e1516 100644 --- a/src/image/png/reader.go +++ b/src/image/png/reader.go @@ -326,9 +326,15 @@ func (d *decoder) decode() (image.Image, error) { var img image.Image if d.interlace == itNone { img, err = d.readImagePass(r, 0, false) + if err != nil { + return nil, err + } } else if d.interlace == itAdam7 { // Allocate a blank image of the full size. img, err = d.readImagePass(nil, 0, true) + if err != nil { + return nil, err + } for pass := 0; pass < 7; pass++ { imagePass, err := d.readImagePass(r, pass, false) if err != nil { @@ -430,6 +436,9 @@ func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image // Read the decompressed bytes. _, err := io.ReadFull(r, cr) if err != nil { + if err == io.EOF || err == io.ErrUnexpectedEOF { + return nil, FormatError("not enough pixel data") + } return nil, err } diff --git a/src/image/png/reader_test.go b/src/image/png/reader_test.go index 9f24f041e5..1f92f8c221 100644 --- a/src/image/png/reader_test.go +++ b/src/image/png/reader_test.go @@ -320,6 +320,21 @@ func TestPalettedDecodeConfig(t *testing.T) { } } +func TestIncompleteIDATOnRowBoundary(t *testing.T) { + // The following is an invalid 1x2 grayscale PNG image. The header is OK, + // but the zlib-compressed IDAT payload contains two bytes "\x02\x00", + // which is only one row of data (the leading "\x02" is a row filter). + const ( + ihdr = "\x00\x00\x00\x0dIHDR\x00\x00\x00\x01\x00\x00\x00\x02\x08\x00\x00\x00\x00\xbc\xea\xe9\xfb" + idat = "\x00\x00\x00\x0eIDAT\x78\x9c\x62\x62\x00\x04\x00\x00\xff\xff\x00\x06\x00\x03\xfa\xd0\x59\xae" + iend = "\x00\x00\x00\x00IEND\xae\x42\x60\x82" + ) + _, err := Decode(strings.NewReader(pngHeader + ihdr + idat + iend)) + if err == nil { + t.Fatal("got nil error, want non-nil") + } +} + func TestMultipletRNSChunks(t *testing.T) { /* The following is a valid 1x1 paletted PNG image with a 1-element palette