Commit 3403ee52 authored by Stephan Zuercher's avatar Stephan Zuercher Committed by Nigel Tao

image/png: fix palette extension to handle 255 color images

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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarNigel Tao <nigeltao@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 503e6ccd
...@@ -706,7 +706,7 @@ func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image ...@@ -706,7 +706,7 @@ func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image
} }
} }
case cbP8: case cbP8:
if len(paletted.Palette) != 255 { if len(paletted.Palette) != 256 {
for x := 0; x < width; x++ { for x := 0; x < width; x++ {
if len(paletted.Palette) <= int(cdat[x]) { if len(paletted.Palette) <= int(cdat[x]) {
paletted.Palette = paletted.Palette[:int(cdat[x])+1] paletted.Palette = paletted.Palette[:int(cdat[x])+1]
......
...@@ -584,6 +584,21 @@ func TestUnknownChunkLengthUnderflow(t *testing.T) { ...@@ -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) { func TestGray8Transparent(t *testing.T) {
// These bytes come from https://golang.org/issues/19553 // These bytes come from https://golang.org/issues/19553
m, err := Decode(bytes.NewReader([]byte{ m, err := Decode(bytes.NewReader([]byte{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment