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()