]> Cypherpunks repositories - gostls13.git/commitdiff
image/gif: accept LZW encodings that do not have an explicit end marker.
authorNigel Tao <nigeltao@golang.org>
Mon, 29 Jun 2015 06:43:25 +0000 (16:43 +1000)
committerNigel Tao <nigeltao@golang.org>
Tue, 30 Jun 2015 03:47:51 +0000 (03:47 +0000)
The spec says this is invalid, but it matches giflib's behavior.

Fixes #9856 (together with https://go-review.googlesource.com/11661).

Change-Id: I05701f62a9e5e724a2d85c6b87ae4111e537146b
Reviewed-on: https://go-review.googlesource.com/11663
Reviewed-by: Rob Pike <r@golang.org>
src/image/gif/reader.go

index cf5af210a609c1a8bbd93fac2e8a8cb815269eac..a1da69780c9e2449789d4da018c22c0db8b051a3 100644 (file)
@@ -202,9 +202,18 @@ func (d *decoder) decode(r io.Reader, configOnly bool) error {
                                }
                                return errNotEnough
                        }
-                       // Both lzwr and br should be exhausted. Reading from them
-                       // should yield (0, io.EOF).
-                       if n, err := lzwr.Read(d.tmp[:1]); n != 0 || err != io.EOF {
+                       // Both lzwr and br should be exhausted. Reading from them should
+                       // yield (0, io.EOF).
+                       //
+                       // The spec (Appendix F - Compression), says that "An End of
+                       // Information code... must be the last code output by the encoder
+                       // for an image". In practice, though, giflib (a widely used C
+                       // library) does not enforce this, so we also accept lzwr returning
+                       // io.ErrUnexpectedEOF (meaning that the encoded stream hit io.EOF
+                       // before the LZW decoder saw an explict end code), provided that
+                       // the io.ReadFull call above successfully read len(m.Pix) bytes.
+                       // See http://golang.org/issue/9856 for an example GIF.
+                       if n, err := lzwr.Read(d.tmp[:1]); n != 0 || (err != io.EOF && err != io.ErrUnexpectedEOF) {
                                if err != nil {
                                        return err
                                }