tiff: limit uncompressed data reads Apply the same limit to reading uncompressed data as we use for compressed data. Change-Id: Ib9f9243813659b93c02c9e94567697636a6a6964 Reviewed-on: https://go-review.googlesource.com/c/image/+/790220 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Neal Patel <neal@golang.org> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Neal Patel <nealpatel@google.com>
diff --git a/tiff/reader.go b/tiff/reader.go index bb48e8a..d974d79 100644 --- a/tiff/reader.go +++ b/tiff/reader.go
@@ -764,6 +764,9 @@ // but some tools interpret a missing Compression value as none, so we do // the same. case cNone, 0: + if n > blockMaxDataSize { + return nil, FormatError("block data size too large") + } if b, ok := d.r.(*buffer); ok { d.buf, err = b.Slice(offset, n) } else {
diff --git a/tiff/reader_test.go b/tiff/reader_test.go index 0a6b6c7..bf59fdd 100644 --- a/tiff/reader_test.go +++ b/tiff/reader_test.go
@@ -723,3 +723,48 @@ t.Fatalf("Decode: got %v, want error containing %q", err, want) } } + +func TestDecodeBlockDataSizeTooLarge(t *testing.T) { + t.Run("strip", func(t *testing.T) { + // 1x1 image, blockMaxDataSize = 1 * 1 * 8 = 8. + // StripByteCounts is set to 9. + enc := binary.BigEndian + data := newTIFF(enc) + data = appendIFD(data, enc, map[uint16]any{ + tImageWidth: uint32(1), + tImageLength: uint32(1), + tStripOffsets: []uint32{8}, + tStripByteCounts: []uint32{9}, + tPhotometricInterpretation: uint16(pBlackIsZero), + tBitsPerSample: uint16(8), + }) + + _, err := Decode(bytes.NewReader(data)) + if want := "block data size too large"; err == nil || !strings.Contains(err.Error(), want) { + t.Fatalf("Decode: got %v, want error containing %q", err, want) + } + }) + + t.Run("tile", func(t *testing.T) { + // 16x16 image with 16x16 tiles. + // blockMaxDataSize = 16 * 16 * 8 = 2048. + // TileByteCounts is set to 2049. + enc := binary.BigEndian + data := newTIFF(enc) + data = appendIFD(data, enc, map[uint16]any{ + tImageWidth: uint32(16), + tImageLength: uint32(16), + tTileWidth: uint32(16), + tTileLength: uint32(16), + tTileOffsets: []uint32{8}, + tTileByteCounts: []uint32{2049}, + tPhotometricInterpretation: uint16(pBlackIsZero), + tBitsPerSample: uint16(8), + }) + + _, err := Decode(bytes.NewReader(data)) + if want := "block data size too large"; err == nil || !strings.Contains(err.Error(), want) { + t.Fatalf("Decode: got %v, want error containing %q", err, want) + } + }) +}