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 <nigeltao@golang.org>
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 @@
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 @@
}
}
+// 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.