From: Nigel Tao Date: Mon, 13 Apr 2015 03:25:28 +0000 (+1000) Subject: image/jpeg: don't assume that an ensureNBits failure implies that we can X-Git-Tag: go1.5beta1~1126 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2f98bac3107d3dee4f546055e790cf0076454c80;p=gostls13.git image/jpeg: don't assume that an ensureNBits failure implies that we can call unreadByteStuffedByte. If ensureNBits was due to an io.EOF that was translated to jpeg.errShortHuffmanData, then we may have read no bytes, so there is no byte-stuffed-byte to unread. Fixes #10387 Change-Id: I39a3842590c6cef2aa48943288d52f603338b44d Reviewed-on: https://go-review.googlesource.com/8841 Reviewed-by: Rob Pike --- diff --git a/src/image/jpeg/reader.go b/src/image/jpeg/reader.go index 2c3c2f72f8..435b67a020 100644 --- a/src/image/jpeg/reader.go +++ b/src/image/jpeg/reader.go @@ -170,7 +170,7 @@ func (d *decoder) fill() error { // can happen when expecting to read a 0xff 0x00 byte-stuffed byte. func (d *decoder) unreadByteStuffedByte() { if d.bytes.nUnreadable == 0 { - panic("jpeg: unreadByteStuffedByte call cannot be fulfilled") + return } d.bytes.i -= d.bytes.nUnreadable d.bytes.nUnreadable = 0 @@ -242,12 +242,7 @@ func (d *decoder) readByteStuffedByte() (x byte, err error) { // stuffing. func (d *decoder) readFull(p []byte) error { // Unread the overshot bytes, if any. - if d.bytes.nUnreadable != 0 { - if d.bits.n >= 8 { - d.unreadByteStuffedByte() - } - d.bytes.nUnreadable = 0 - } + d.unreadByteStuffedByte() for { n := copy(p, d.bytes.buf[d.bytes.i:d.bytes.j]) @@ -269,12 +264,7 @@ func (d *decoder) readFull(p []byte) error { // ignore ignores the next n bytes. func (d *decoder) ignore(n int) error { // Unread the overshot bytes, if any. - if d.bytes.nUnreadable != 0 { - if d.bits.n >= 8 { - d.unreadByteStuffedByte() - } - d.bytes.nUnreadable = 0 - } + d.unreadByteStuffedByte() for { m := d.bytes.j - d.bytes.i diff --git a/src/image/jpeg/reader_test.go b/src/image/jpeg/reader_test.go index c5a36cba21..5964b92aac 100644 --- a/src/image/jpeg/reader_test.go +++ b/src/image/jpeg/reader_test.go @@ -186,6 +186,26 @@ func pixString(pix []byte, stride, x, y int) string { return s.String() } +func TestTruncatedSOSDataDoesntPanic(t *testing.T) { + b, err := ioutil.ReadFile("../testdata/video-005.gray.q50.jpeg") + if err != nil { + t.Fatal(err) + } + sosMarker := []byte{0xff, 0xda} + i := bytes.Index(b, sosMarker) + if i < 0 { + t.Fatal("SOS marker not found") + } + i += len(sosMarker) + j := i + 10 + if j > len(b) { + j = len(b) + } + for ; i < j; i++ { + Decode(bytes.NewReader(b[:i])) + } +} + func TestExtraneousData(t *testing.T) { // Encode a 1x1 red image. src := image.NewRGBA(image.Rect(0, 0, 1, 1))