diff --git a/tiff/reader.go b/tiff/reader.go index 66acb0d..0b24c53 100644 --- a/tiff/reader.go +++ b/tiff/reader.go @@ -488,6 +488,13 @@ func Decode(r io.Reader) (img image.Image, err error) { blocksAcross := 1 blocksDown := 1 + if d.config.Width == 0 { + blocksAcross = 0 + } + if d.config.Height == 0 { + blocksDown = 0 + } + var blockOffsets, blockCounts []uint if int(d.firstVal(tTileWidth)) != 0 { @@ -496,8 +503,12 @@ func Decode(r io.Reader) (img image.Image, err error) { blockWidth = int(d.firstVal(tTileWidth)) blockHeight = int(d.firstVal(tTileLength)) - blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth - blocksDown = (d.config.Height + blockHeight - 1) / blockHeight + if blockWidth != 0 { + blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth + } + if blockHeight != 0 { + blocksDown = (d.config.Height + blockHeight - 1) / blockHeight + } blockCounts = d.features[tTileByteCounts] blockOffsets = d.features[tTileOffsets] @@ -507,7 +518,9 @@ func Decode(r io.Reader) (img image.Image, err error) { blockHeight = int(d.firstVal(tRowsPerStrip)) } - blocksDown = (d.config.Height + blockHeight - 1) / blockHeight + if blockHeight != 0 { + blocksDown = (d.config.Height + blockHeight - 1) / blockHeight + } blockOffsets = d.features[tStripOffsets] blockCounts = d.features[tStripByteCounts] diff --git a/tiff/reader_test.go b/tiff/reader_test.go index cceb7aa..5bd5ee2 100644 --- a/tiff/reader_test.go +++ b/tiff/reader_test.go @@ -5,6 +5,7 @@ package tiff import ( + "bytes" "image" "io/ioutil" "os" @@ -162,6 +163,31 @@ func TestDecompress(t *testing.T) { } } +// Do not panic when image dimensions are zero, return zero-sized +// image instead. +// Issue 10393. +func TestZeroSizedImages(t *testing.T) { + testsizes := []struct { + w, h int + }{ + {0, 0}, + {1, 0}, + {0, 1}, + {1, 1}, + } + for _, r := range testsizes { + img := image.NewRGBA(image.Rect(0, 0, r.w, r.h)) + var buf bytes.Buffer + if err := Encode(&buf, img, nil); err != nil { + t.Errorf("encode w=%d h=%d: %v", r.w, r.h, err) + continue + } + if _, err := Decode(&buf); err != nil { + t.Errorf("decode w=%d h=%d: %v", r.w, r.h, err) + } + } +} + // benchmarkDecode benchmarks the decoding of an image. func benchmarkDecode(b *testing.B, filename string) { b.StopTimer()