diff options
author | Russ Cox <rsc@golang.org> | 2014-11-22 13:55:33 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-11-22 13:55:33 -0500 |
commit | 9cc4768f52e6c4a852f863a3a6b982ea71a4ed43 (patch) | |
tree | 85f581df9882b8bb3f45f5e74537abc7cd44df8f | |
parent | f3c4b8737a5661029662c01e1dab0d38541f39ec (diff) | |
download | go-9cc4768f52e6c4a852f863a3a6b982ea71a4ed43.tar.gz |
image/jpeg: handle Read returning n > 0, err != nil in d.fill
Fixes issue 9127.
LGTM=r
R=bradfitz, r
CC=golang-codereviews, nigeltao
https://codereview.appspot.com/178120043
-rw-r--r-- | src/image/jpeg/reader.go | 3 | ||||
-rw-r--r-- | src/image/jpeg/reader_test.go | 46 |
2 files changed, 49 insertions, 0 deletions
diff --git a/src/image/jpeg/reader.go b/src/image/jpeg/reader.go index c8fae3cea..6d8b1d1d0 100644 --- a/src/image/jpeg/reader.go +++ b/src/image/jpeg/reader.go @@ -143,6 +143,9 @@ func (d *decoder) fill() error { // Fill in the rest of the buffer. n, err := d.r.Read(d.bytes.buf[d.bytes.j:]) d.bytes.j += n + if n > 0 { + err = nil + } return err } diff --git a/src/image/jpeg/reader_test.go b/src/image/jpeg/reader_test.go index 93f4adab9..4de2e8ee7 100644 --- a/src/image/jpeg/reader_test.go +++ b/src/image/jpeg/reader_test.go @@ -9,6 +9,7 @@ import ( "fmt" "image" "image/color" + "io" "io/ioutil" "math/rand" "os" @@ -88,6 +89,51 @@ func decodeFile(filename string) (image.Image, error) { return Decode(f) } +type eofReader struct { + data []byte // deliver from Read without EOF + dataEOF []byte // then deliver from Read with EOF on last chunk + lenAtEOF int +} + +func (r *eofReader) Read(b []byte) (n int, err error) { + if len(r.data) > 0 { + n = copy(b, r.data) + r.data = r.data[n:] + } else { + n = copy(b, r.dataEOF) + r.dataEOF = r.dataEOF[n:] + if len(r.dataEOF) == 0 { + err = io.EOF + if r.lenAtEOF == -1 { + r.lenAtEOF = n + } + } + } + return +} + +func TestDecodeEOF(t *testing.T) { + // Check that if reader returns final data and EOF at same time, jpeg handles it. + data, err := ioutil.ReadFile("../testdata/video-001.jpeg") + if err != nil { + t.Fatal(err) + } + + n := len(data) + for i := 0; i < n; { + r := &eofReader{data[:n-i], data[n-i:], -1} + _, err := Decode(r) + if err != nil { + t.Errorf("Decode with Read() = %d, EOF: %v", r.lenAtEOF, err) + } + if i == 0 { + i = 1 + } else { + i *= 2 + } + } +} + // check checks that the two pix data are equal, within the given bounds. func check(bounds image.Rectangle, pix0, pix1 []byte, stride0, stride1 int) error { if stride0 <= 0 || stride0%8 != 0 { |