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>
This commit is contained in:
Benny Siegert 2015-04-28 20:02:45 +02:00 коммит произвёл Nigel Tao
Родитель 918b3735c3
Коммит 6af46c2009
2 изменённых файлов: 23 добавлений и 0 удалений

Просмотреть файл

@ -15,6 +15,7 @@ import (
"image/color" "image/color"
"io" "io"
"io/ioutil" "io/ioutil"
"math"
"golang.org/x/image/tiff/lzw" "golang.org/x/image/tiff/lzw"
) )
@ -72,6 +73,9 @@ func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
var raw []byte var raw []byte
datatype := d.byteOrder.Uint16(p[2:4]) datatype := d.byteOrder.Uint16(p[2:4])
count := d.byteOrder.Uint32(p[4:8]) 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 { if datalen := lengths[datatype] * count; datalen > 4 {
// The IFD contains a pointer to the real value. // The IFD contains a pointer to the real value.
raw = make([]byte, datalen) raw = make([]byte, datalen)

Просмотреть файл

@ -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. // benchmarkDecode benchmarks the decoding of an image.
func benchmarkDecode(b *testing.B, filename string) { func benchmarkDecode(b *testing.B, filename string) {
b.StopTimer() b.StopTimer()