x/image/tiff: fix division by zero when decoding empty image
Return a zero width or zero height image of the appropriate type.
Fixes golang/go#10393.
Change-Id: I3aa7b6125447726600fb072ce1e8682373ce2a57
Reviewed-on: https://go-review.googlesource.com/9182
Reviewed-by: Nigel Tao <nigeltao@golang.org>
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 @@
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 @@
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 @@
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 @@
}
}
+// 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()