]> Cypherpunks repositories - gostls13.git/commitdiff
image/png: fix palette extension to handle 255 color images
authorStephan Zuercher <zuercher@gmail.com>
Mon, 6 May 2019 17:55:45 +0000 (10:55 -0700)
committerNigel Tao <nigeltao@golang.org>
Wed, 8 May 2019 01:49:03 +0000 (01:49 +0000)
The PNG decode path attempts to handle paletted images that refer to
non-existent palette indicies. This PR fixes a corner case were images
that have exactly 255 palette colors and an IDAT chunk that references
palette index 255 produce an invalid image such that invoking At on
the pixel(s) in question causes an index out of range panic.

Fixes #31830

Change-Id: I34c44d9de5b9d76fe8c45c04e866fbc7f51f2a9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/175397
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/image/png/reader.go
src/image/png/reader_test.go
src/image/png/testdata/invalid-palette.png [new file with mode: 0644]

index 53fbf3e00a7cb755b5c6071e7f6eb62f9633f8a7..6771973bda9f6cd0b3a1a45f20db111b3b7bbe3b 100644 (file)
@@ -706,7 +706,7 @@ func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image
                                }
                        }
                case cbP8:
-                       if len(paletted.Palette) != 255 {
+                       if len(paletted.Palette) != 256 {
                                for x := 0; x < width; x++ {
                                        if len(paletted.Palette) <= int(cdat[x]) {
                                                paletted.Palette = paletted.Palette[:int(cdat[x])+1]
index 33dcd3debcc96e85eb2e9426e310a48f07368a1d..3325d2e8a59bb906d563ef34ae4b43413c04a9ca 100644 (file)
@@ -584,6 +584,21 @@ func TestUnknownChunkLengthUnderflow(t *testing.T) {
        }
 }
 
+func TestPaletted8OutOfRangePixel(t *testing.T) {
+       // IDAT contains a reference to a palette index that does not exist in the file.
+       img, err := readPNG("testdata/invalid-palette.png")
+       if err != nil {
+               t.Errorf("decoding invalid-palette.png: unexpected error %v", err)
+               return
+       }
+
+       // Expect that the palette is extended with opaque black.
+       want := color.RGBA{0x00, 0x00, 0x00, 0xff}
+       if got := img.At(15, 15); got != want {
+               t.Errorf("got %F %v, expected %T %v", got, got, want, want)
+       }
+}
+
 func TestGray8Transparent(t *testing.T) {
        // These bytes come from https://golang.org/issues/19553
        m, err := Decode(bytes.NewReader([]byte{
diff --git a/src/image/png/testdata/invalid-palette.png b/src/image/png/testdata/invalid-palette.png
new file mode 100644 (file)
index 0000000..a747e59
Binary files /dev/null and b/src/image/png/testdata/invalid-palette.png differ