git.lucas.co / go_mono
git clone https://git.lucas.co/go_mono.git

commit6af46c2009eff7ae6513cefd15dd406f35766fb0
parent918b3735c3
authorBenny Siegert <bsiegert@gmail.com>
date2015-04-28 20:02
tiff: reject IFDs whose data is longer than int.

Fixes golang/go#10596

Change-Id: Ib5035569e84c67868c7f278281620f6c9b11b470
Reviewed-on: https://go-review.googlesource.com/9378
Reviewed-by: Nigel Tao <nigeltao@golang.org>

 tiff/reader.go      |  4 ++++
 tiff/reader_test.go | 19 +++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/tiff/reader.go b/tiff/reader.go
index 146ba59..94c4cf7 100644
--- a/tiff/reader.go
+++ b/tiff/reader.go
@@ -15,6 +15,7 @@ import (
 	"image/color"
 	"io"
 	"io/ioutil"
+	"math"
 
 	"golang.org/x/image/tiff/lzw"
 )
@@ -72,6 +73,9 @@ func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
 	var raw []byte
 	datatype := d.byteOrder.Uint16(p[2:4])
 	count := d.byteOrder.Uint32(p[4:8])
+	if count > math.MaxInt32/lengths[datatype] {
+		return nil, FormatError("IFD data too large")
+	}
 	if datalen := lengths[datatype] * count; datalen > 4 {
 		// The IFD contains a pointer to the real value.
 		raw = make([]byte, datalen)
diff --git a/tiff/reader_test.go b/tiff/reader_test.go
index 5041099..d79c9e9 100644
--- a/tiff/reader_test.go
+++ b/tiff/reader_test.go
@@ -214,6 +214,25 @@ func TestZeroSizedImages(t *testing.T) {
 	}
 }
 
+// TestLargeIFDEntry verifies that a large IFD entry does not cause Decode
+// to panic.
+// Issue 10596.
+func TestLargeIFDEntry(t *testing.T) {
+	testdata := "II*\x00\x08\x00\x00\x00\f\x000000000000" +
+		"00000000000000000000" +
+		"00000000000000000000" +
+		"00000000000000000000" +
+		"00000000000000\x17\x01\x04\x00\x01\x00" +
+		"\x00\xc0000000000000000000" +
+		"00000000000000000000" +
+		"00000000000000000000" +
+		"000000"
+	_, err := Decode(strings.NewReader(testdata))
+	if err == nil {
+		t.Fatal("Decode with large IFD entry: got nil error, want non-nil")
+	}
+}
+
 // benchmarkDecode benchmarks the decoding of an image.
 func benchmarkDecode(b *testing.B, filename string) {
 	b.StopTimer()