[libpng14] Prevent writing over-length PLTE chunk (Cosmin Truta) and

silently truncate over-length PLTE chunk while reading.
This commit is contained in:
Glenn Randers-Pehrson 2015-10-31 07:56:39 -05:00
parent 82c5abc170
commit fd97f3e31e
4 changed files with 31 additions and 7 deletions

View File

@ -3586,6 +3586,11 @@ PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS.
We removed the trailing '.' from the warning and error messages.
Starting with libpng-1.4.17, attempting to set an over-length PLTE chunk
is an error. Previously this requirement of the PNG specification was not
enforced, and the palette was always limited to 256 entries. An over-length
PLTE chunk found in an input PNG is silently truncated.
.SH X. Detecting libpng
The png_get_io_ptr() function has been present since libpng-0.88, has never

View File

@ -551,7 +551,7 @@ void /* PRIVATE */
png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_color palette[PNG_MAX_PALETTE_LENGTH];
int num, i;
int max_palette_length, num, i;
#ifdef PNG_POINTER_INDEXING_SUPPORTED
png_colorp pal_ptr;
#endif
@ -603,8 +603,19 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
}
}
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
/* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
num = (int)length / 3;
/* If the palette has 256 or fewer entries but is too large for the bit depth,
* we don't issue an error, to preserve the behavior of previous libpng versions.
* We silently truncate the unused extra palette entries here.
*/
if (num > max_palette_length)
num = max_palette_length;
#ifdef PNG_POINTER_INDEXING_SUPPORTED
for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
{

View File

@ -1,7 +1,7 @@
/* pngset.c - storage of image information into info struct
*
* Last changed in libpng 1.4.17 [October 28, 2015]
* Last changed in libpng 1.4.17 [October 31, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -427,12 +427,17 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
png_colorp palette, int num_palette)
{
png_uint_32 max_palette_length;
png_debug1(1, "in %s storage function", "PLTE");
if (png_ptr == NULL || info_ptr == NULL)
return;
if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if (num_palette < 0 || num_palette > (int) max_palette_length)
{
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
png_error(png_ptr, "Invalid palette length");
@ -450,8 +455,8 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
/* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
* of num_palette entries, in case of an invalid PNG file that has
* too-large sample values.
* of num_palette entries, in case of an invalid PNG file or incorrect
* call to png_set_PLTE() with too-large sample values.
*/
png_ptr->palette = (png_colorp)png_calloc(png_ptr,
PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));

View File

@ -601,17 +601,20 @@ void /* PRIVATE */
png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
{
PNG_PLTE;
png_uint_32 i;
png_uint_32 max_palette_length, i;
png_colorp pal_ptr;
png_byte buf[3];
png_debug(1, "in png_write_PLTE");
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if ((
#ifdef PNG_MNG_FEATURES_SUPPORTED
!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
#endif
num_pal == 0) || num_pal > 256)
num_pal == 0) || num_pal > max_palette_length)
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{