| Index: src/images/SkImageDecoder_libpng.cpp
|
| diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
|
| index f9ef6b7942306016c714668555d96b7c3c31fbb3..391139a9ff3581b180c9dbdf686767c49808012d 100644
|
| --- a/src/images/SkImageDecoder_libpng.cpp
|
| +++ b/src/images/SkImageDecoder_libpng.cpp
|
| @@ -97,7 +97,7 @@ private:
|
| SkPNGImageIndex* fImageIndex;
|
|
|
| bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_ptrp);
|
| - bool decodePalette(png_structp png_ptr, png_infop info_ptr,
|
| + bool decodePalette(png_structp png_ptr, png_infop info_ptr, int bitDepth,
|
| bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap,
|
| SkColorTable **colorTablep);
|
| bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha,
|
| @@ -350,7 +350,7 @@ SkImageDecoder::Result SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap
|
| SkColorTable* colorTable = NULL;
|
|
|
| if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
|
| - decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable);
|
| + decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, &colorTable);
|
| }
|
|
|
| SkAutoUnref aur(colorTable);
|
| @@ -651,7 +651,8 @@ bool SkPNGImageDecoder::getBitmapColorType(png_structp png_ptr, png_infop info_p
|
| typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
|
|
| bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
|
| - bool *hasAlphap, bool *reallyHasAlphap,
|
| + int bitDepth, bool *hasAlphap,
|
| + bool *reallyHasAlphap,
|
| SkColorTable **colorTablep) {
|
| int numPalette;
|
| png_colorp palette;
|
| @@ -660,13 +661,6 @@ bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
|
|
|
| png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette);
|
|
|
| - /* BUGGY IMAGE WORKAROUND
|
| -
|
| - We hit some images (e.g. fruit_.png) who contain bytes that are == colortable_count
|
| - which is a problem since we use the byte as an index. To work around this we grow
|
| - the colortable by 1 (if its < 256) and duplicate the last color into that slot.
|
| - */
|
| - int colorCount = numPalette + (numPalette < 256);
|
| SkPMColor colorStorage[256]; // worst-case storage
|
| SkPMColor* colorPtr = colorStorage;
|
|
|
| @@ -705,9 +699,19 @@ bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
|
| palette++;
|
| }
|
|
|
| - // see BUGGY IMAGE WORKAROUND comment above
|
| - if (numPalette < 256) {
|
| - *colorPtr = colorPtr[-1];
|
| + /* BUGGY IMAGE WORKAROUND
|
| +
|
| + Invalid images could contain pixel values that are greater than the number of palette
|
| + entries. Since we use pixel values as indices into the palette this could result in reading
|
| + beyond the end of the palette which could leak the contents of uninitialized memory. To
|
| + ensure this doesn't happen, we grow the colortable to the maximum size that can be
|
| + addressed by the bitdepth of the image and fill it with the last palette color or black if
|
| + the palette is empty (really broken image).
|
| + */
|
| + int colorCount = SkTMax(numPalette, 1 << SkTMin(bitDepth, 8));
|
| + SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0);
|
| + for (; index < colorCount; index++) {
|
| + *colorPtr++ = lastColor;
|
| }
|
|
|
| *colorTablep = SkNEW_ARGS(SkColorTable, (colorStorage, colorCount));
|
| @@ -797,7 +801,7 @@ bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) {
|
| SkColorTable* colorTable = NULL;
|
|
|
| if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
|
| - decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable);
|
| + decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, &colorTable);
|
| }
|
|
|
| SkAutoUnref aur(colorTable);
|
|
|