]> Cypherpunks.ru repositories - gostls13.git/commitdiff
image/jpeg: handle Read returning n > 0, err != nil in d.fill
authorRuss Cox <rsc@golang.org>
Sat, 22 Nov 2014 18:55:33 +0000 (13:55 -0500)
committerRuss Cox <rsc@golang.org>
Sat, 22 Nov 2014 18:55:33 +0000 (13:55 -0500)
Fixes #9127.

LGTM=r
R=bradfitz, r
CC=golang-codereviews, nigeltao
https://golang.org/cl/178120043

src/image/jpeg/reader.go
src/image/jpeg/reader_test.go

index c8fae3cea96562be1f184a730e28bb22ad88ec2d..6d8b1d1d036c84b57e53e937f780b8663d999fa3 100644 (file)
@@ -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
 }
 
index 93f4adab9dc88dac047b00e4da888bedbcae1b07..4de2e8ee7371585bdd625a7bb03c094845623ff9 100644 (file)
@@ -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 {