From 1bef8e97995c33123665582e57d3ed40b57d5978 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Fri, 30 Oct 2015 11:34:37 -0500 Subject: [PATCH] [libpng16] Silently truncate over-length PLTE chunk while reading. --- ANNOUNCE | 3 ++- CHANGES | 3 ++- pngrutil.c | 15 +++++++++++---- pngset.c | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index e41c5a074..41726182f 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -107,7 +107,8 @@ Version 1.6.19rc01 [October 23, 2015] No changes. Version 1.6.19rc02 [October 30, 2015] - Prevent reading or writing over-length PLTE chunk (Cosmin Truta). + Prevent setting or writing over-length PLTE chunk (Cosmin Truta). + Silently truncate over-length PLTE chunk while reading. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 7c9977e15..e15f58b92 100644 --- a/CHANGES +++ b/CHANGES @@ -5392,7 +5392,8 @@ Version 1.6.19rc01 [October 23, 2015] No changes. Version 1.6.19rc02 [October 30, 2015] - Prevent reading or writing over-length PLTE chunk (Cosmin Truta). + Prevent setting or writing over-length PLTE chunk (Cosmin Truta). + Silently truncate over-length PLTE chunk while reading. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/pngrutil.c b/pngrutil.c index babf5c02d..6d35445ed 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -872,7 +872,7 @@ void /* PRIVATE */ png_handle_PLTE(png_structrp png_ptr, png_inforp 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 @@ -930,9 +930,19 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) return; } + 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++) { @@ -1002,9 +1012,6 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * confusing. * * Fix this by not sharing the palette in this way. - * - * Starting with libpng-1.6.19, png_set_PLTE() also issues a png_error() when - * it attempts to set a palette length that is too large for the bit depth. */ png_set_PLTE(png_ptr, info_ptr, palette, num); diff --git a/pngset.c b/pngset.c index 0629d94e9..8dcf18afc 100644 --- a/pngset.c +++ b/pngset.c @@ -523,7 +523,7 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, 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 > 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");