summaryrefslogtreecommitdiff
path: root/src/image
diff options
context:
space:
mode:
authorNigel Tao <nigeltao@golang.org>2021-10-08 10:33:47 +1100
committerNigel Tao <nigeltao@golang.org>2021-10-08 01:18:01 +0000
commit8c4ea3140e7c79d828fe7683a3dfe3474a9938fb (patch)
treefd94e9048861b6f0472898429464166aa14b9a6e /src/image
parent78d749fbe978bf6eac9c5e11aa4641dc126c9128 (diff)
downloadgo-git-8c4ea3140e7c79d828fe7683a3dfe3474a9938fb.tar.gz
image/png: fix interlaced palette out-of-bounds
PNG images can be paletted, where each pixel value (a uint8) indexes a slice of colors. In terms of wire format, the PLTE chunk explicitly contains the palette length. However, in practice, some arguably malformed images contain pixel values greater than or equal to the explicit PLTE length. Go's image/png decoder accomodates such images by lengthening the decoded image's palette if the implicit maximum is larger than the explicit maximum. This was already done, prior to this commit, by the "if len(paletted.Palette) <= int(idx)" lines in decoder.readImagePass. Separately, PNG images can also be interlaced, where the final image is the result of merging multiple partial images, also called passes. Prior to this commit, we applied the palette lengthening to the pass images but not the final image. This commit fixes that. Fixes #48612 Change-Id: I77606538cc9a504fbd726071756ebcd10c9da73f Reviewed-on: https://go-review.googlesource.com/c/go/+/354709 Trust: Nigel Tao <nigeltao@golang.org> Reviewed-by: Andrew Gerrand <adg@golang.org>
Diffstat (limited to 'src/image')
-rw-r--r--src/image/png/reader.go10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/image/png/reader.go b/src/image/png/reader.go
index 910520bd4b..4c65038cb5 100644
--- a/src/image/png/reader.go
+++ b/src/image/png/reader.go
@@ -821,9 +821,17 @@ func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) {
dstPix, stride, rect = target.Pix, target.Stride, target.Rect
bytesPerPixel = 8
case *image.Paletted:
- srcPix = src.(*image.Paletted).Pix
+ source := src.(*image.Paletted)
+ srcPix = source.Pix
dstPix, stride, rect = target.Pix, target.Stride, target.Rect
bytesPerPixel = 1
+ if len(target.Palette) < len(source.Palette) {
+ // readImagePass can return a paletted image whose implicit palette
+ // length (one more than the maximum Pix value) is larger than the
+ // explicit palette length (what's in the PLTE chunk). Make the
+ // same adjustment here.
+ target.Palette = source.Palette
+ }
case *image.RGBA:
srcPix = src.(*image.RGBA).Pix
dstPix, stride, rect = target.Pix, target.Stride, target.Rect