From 3403ee524bef9f6d2d69e11410fbf16854447d21 Mon Sep 17 00:00:00 2001 From: Stephan Zuercher Date: Mon, 6 May 2019 10:55:45 -0700 Subject: [PATCH] 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 Run-TryBot: Brad Fitzpatrick Reviewed-by: Brad Fitzpatrick Reviewed-by: Nigel Tao TryBot-Result: Gobot Gobot --- src/image/png/reader.go | 2 +- src/image/png/reader_test.go | 15 +++++++++++++++ src/image/png/testdata/invalid-palette.png | Bin 0 -> 1122 bytes 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/image/png/testdata/invalid-palette.png diff --git a/src/image/png/reader.go b/src/image/png/reader.go index 53fbf3e00a..6771973bda 100644 --- a/src/image/png/reader.go +++ b/src/image/png/reader.go @@ -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] diff --git a/src/image/png/reader_test.go b/src/image/png/reader_test.go index 33dcd3debc..3325d2e8a5 100644 --- a/src/image/png/reader_test.go +++ b/src/image/png/reader_test.go @@ -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 index 0000000000000000000000000000000000000000..a747e594443fe61ed204621bdff632c2d250ad4f GIT binary patch literal 1122 zcmWlZS6B!P07XxwG&E4DXb>ujA|qv#Qjw%WO4=f1G?k=KvdNZ=j0z!|LI}|=l|tF8 zNs4Iv{SWt^@4lb!#@JY!ONuLr1Co{&rnY^Q`9GpUeXXe@Z3lwgHdgj#z0iX|H-cRV z{iEMsggX)WL;v51b|BV{_%9^d81NIxA4s(#-GWRr1DhDs$lwNKza#ez`L7K5g2HDM zKcV!Ip&uCb9_4qayhXJhwK|5sVZ>|HUoo+9*9le}$NLy7kFx3rK8INy%bG*1J&5lC*6nBg zJ~r%S;~xBWXX_Rs!ie0=wotZ*uwxTZ z!9)kKGmw}7cKNg0k3AdNyMcY{*}skhz8qZ3p*6&==CBV(R&jJC$Gkbdf)iex^yHKW zaqgUUBi@xWE}UJ?IcLrgY$ z>NRV9*Rg)XMnC_6z@XqwA)%YYw)ANc5xH&qj;QFJF}rr}*}HE)2M!*JJ$&TovEwIB zo{Bpie}=Q?&L>>Bc