From b7cdfbb5c4037753713f496c30ecc6bbe02ebd2c Mon Sep 17 00:00:00 2001 From: "Jeff R. Allen" Date: Sat, 13 Jun 2015 02:45:13 +0200 Subject: [PATCH] image/tiff: fix a panic with invalid tile sizes Fuzzing detected that an invalid tile size could cause a panic. Fix a typo in the range check to solve it. Fixes golang/go#10712. Change-Id: I88a5a7884d98f622cc89ed6e394becebb07c6e60 Reviewed-on: https://go-review.googlesource.com/11020 Reviewed-by: Nigel Tao --- tiff/reader.go | 2 +- tiff/reader_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/tiff/reader.go b/tiff/reader.go index cf9b5e1..19baee9 100644 --- a/tiff/reader.go +++ b/tiff/reader.go @@ -321,7 +321,7 @@ func (d *decoder) decode(dst image.Image, xmin, ymin, xmax, ymax int) error { max := img.PixOffset(rMaxX, y) off := (y - ymin) * (xmax - xmin) * 3 for i := min; i < max; i += 4 { - if d.off+3 > len(d.buf) { + if off+3 > len(d.buf) { return FormatError("not enough pixel data") } img.Pix[i+0] = d.buf[off+0] diff --git a/tiff/reader_test.go b/tiff/reader_test.go index f3d7128..3dd412d 100644 --- a/tiff/reader_test.go +++ b/tiff/reader_test.go @@ -211,6 +211,45 @@ func TestDecompress(t *testing.T) { } } +// TestTileTooBig checks that we do not panic when a tile is too big compared +// to the data available. +// Issue 10712 +func TestTileTooBig(t *testing.T) { + contents, err := ioutil.ReadFile(testdataDir + "video-001-tile-64x64.tiff") + if err != nil { + t.Fatal(err) + } + + // Mutate the loaded image to have the problem. + // + // 0x42 01: tag number (tTileWidth) + // 03 00: data type (short, or uint16) + // 01 00 00 00: count + // xx 00 00 00: value (0x40 -> 0x44: a wider tile consumes more data + // than is available) + find := []byte{0x42, 0x01, 3, 0, 1, 0, 0, 0, 0x40, 0, 0, 0} + repl := []byte{0x42, 0x01, 3, 0, 1, 0, 0, 0, 0x44, 0, 0, 0} + contents = bytes.Replace(contents, find, repl, 1) + + // Turn off the predictor, which makes it possible to hit the + // place with the defect. Without this patch to the image, we run + // out of data too early, and do not hit the part of the code where + // the original panic was. + // + // 42 01: tag number (tPredictor) + // 03 00: data type (short, or uint16) + // 01 00 00 00: count + // xx 00 00 00: value (2 -> 1: 2 = horizontal, 1 = none) + find = []byte{0x3d, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0} + repl = []byte{0x3d, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0} + contents = bytes.Replace(contents, find, repl, 1) + + _, err = Decode(bytes.NewReader(contents)) + if err == nil { + t.Fatal("did not expect nil error") + } +} + // Do not panic when image dimensions are zero, return zero-sized // image instead. // Issue 10393.