From 363ae65e2b20c06895d4c4c065368654ae9eba63 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Thu, 1 Mar 2012 21:39:29 -0600 Subject: [PATCH] [libpng16] Added tests for invalid palette index while reading and writing (work in progress, the latter isn't finished). --- ANNOUNCE | 2 + CHANGES | 2 + pngrtran.c | 124 +++++++++++++++++++++++++++------- pngstruct.h | 13 ++-- pngwrite.c | 7 +- scripts/pnglibconf.dfa | 10 ++- scripts/pnglibconf.h.prebuilt | 5 +- 7 files changed, 126 insertions(+), 37 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index 9339bd47b..a90be28b7 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -250,6 +250,8 @@ Version 1.6.0beta15 [March 2, 2012] allow the error numbers in pngstest to be tuned and checked. makepng also allows generation of images with extra chunks, although this is still work-in-progress. + Added tests for invalid palette index while reading and writing (work in + progress, the latter isn't finished). Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 023ccf012..6efb168d0 100644 --- a/CHANGES +++ b/CHANGES @@ -4002,6 +4002,8 @@ Version 1.6.0beta15 [March 2, 2012] allow the error numbers in pngstest to be tuned and checked. makepng also allows generation of images with extra chunks, although this is still work-in-progress. + Added tests for invalid palette index while reading and writing (work in + progress, the latter isn't finished). Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/pngrtran.c b/pngrtran.c index 8d7ec8821..d662a8df5 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -2294,32 +2294,104 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) png_do_unpack(row_info, png_ptr->row_buf + 1); #endif -/* Added at libpng-1.6.0 */ -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* To do: Fix does not check sub-8-bit rows that have not been unpacked. */ - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - row_info->bit_depth == 8) - if (png_ptr->num_palette < (1 << png_ptr->bit_depth)) - { - if ((png_ptr->interlaced && png_ptr->pass == 6) || - (!png_ptr->interlaced && png_ptr->pass == 0)) - { - png_uint_32 i; - png_bytep rp = png_ptr->row_buf+1; /* +1 to skip the filter byte */ - - for (i = 0; i <= row_info->rowbytes; i++) - { - if (*rp >= png_ptr->num_palette) - { - /* Should this be a benign error instead of a warning? */ - png_warning(png_ptr,"Found invalid palette index"); - break; - } - - rp++; - } - } - } +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Added at libpng-1.5.10 */ + + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_palette < (1 << png_ptr->bit_depth) && + ((png_ptr->interlaced && png_ptr->pass == 6) || + (!png_ptr->interlaced && png_ptr->pass == 0))) + { + png_bytep rp = png_ptr->row_buf + 1 + row_info->rowbytes; + int index, padding; + + switch (row_info->bit_depth) + { + case 1: + { + /* in this case, all bytes must be 0 so we don't need + * to unpack the pixels except for the rightmost one. + */ + padding = 8*row_info->rowbytes - png_ptr->width; + + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp >> padding != 0) + png_ptr->num_palette_max = 1; + padding = 0; + } + + break; + } + + case 2: + { + padding = 2*(4*row_info->rowbytes - png_ptr->width); + + for (; rp > png_ptr->row_buf; rp--) + { + index = ((*rp >> padding) & 0x03); + + if (index > png_ptr->num_palette_max) + png_ptr->num_palette_max = index; + + index = (((*rp >> padding) >> 2) & 0x03); + + if (index > png_ptr->num_palette_max) + png_ptr->num_palette_max = index; + + index = (((*rp >> padding) >> 4) & 0x03); + + if (index > png_ptr->num_palette_max) + png_ptr->num_palette_max = index; + + index = (((*rp >> padding) >> 6) & 0x03); + + if (index > png_ptr->num_palette_max) + png_ptr->num_palette_max = index; + + padding = 0; + } + + break; + } + + case 4: + { + padding = 4*(2*row_info->rowbytes - png_ptr->width); + + for (; rp > png_ptr->row_buf; rp--) + { + index = ((*rp >> padding) & 0x0f); + + if (index > png_ptr->num_palette_max) + png_ptr->num_palette_max = index; + + index = (((*rp >> padding) >> 4) & 0x0f); + + if (index > png_ptr->num_palette_max) + png_ptr->num_palette_max = index; + + padding = 0; + } + + break; + } + + case 8: + { + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp >= png_ptr->num_palette_max) + png_ptr->num_palette_max = *rp; + } + + break; + } + } + } + } #endif #ifdef PNG_READ_BGR_SUPPORTED diff --git a/pngstruct.h b/pngstruct.h index c691aaf0c..c01b31a23 100644 --- a/pngstruct.h +++ b/pngstruct.h @@ -123,6 +123,12 @@ struct png_struct_def png_uint_32 crc; /* current chunk CRC value */ png_colorp palette; /* palette from the input file */ png_uint_16 num_palette; /* number of color entries in palette */ + +/* Added at libpng-1.5.10 */ +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + png_uint_16 num_palette_max; /* maximum palette index found in IDAT */ +#endif + png_uint_16 num_trans; /* number of transparency values */ png_byte compression; /* file compression type (always 0) */ png_byte filter; /* file filter type (always 0) */ @@ -215,13 +221,6 @@ struct png_struct_def int process_mode; /* what push library is currently doing */ int cur_palette; /* current push library palette index */ -# ifdef PNG_TEXT_SUPPORTED - png_size_t current_text_size; /* current size of text input data */ - png_size_t current_text_left; /* how much text left to read in input */ - png_charp current_text; /* current text chunk buffer */ - png_charp current_text_ptr; /* current location in current_text */ -# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ - #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) diff --git a/pngwrite.c b/pngwrite.c index 8281b64f2..c6f772a74 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -731,12 +731,15 @@ png_write_row(png_structrp png_ptr, png_const_bytep row) } #endif -#if 0 /* To do: implement png_do_check_palette_indexes() */ +/* Added at libpng-1.5.10 */ +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED /* Check for out-of-range palette index */ +#if 0 /* To do: implement png_do_check_palette_indexes() */ if (png_ptr->num_palette < (1 << png_ptr->bit_depth)) png_do_check_palette_indexes(&row_info, png_ptr->row_buf + 1, png_ptr->num_palette_max); - if (png_ptr->num_palette_max > num_palette + 1) +#endif + if (png_ptr->num_palette_max > png_ptr->num_palette + 1) png_warning(png_ptr, "Palette index exceeded num_palette"); #endif diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa index 594c8908b..31f24d05b 100644 --- a/scripts/pnglibconf.dfa +++ b/scripts/pnglibconf.dfa @@ -586,7 +586,15 @@ option WRITE_COMPRESSED_TEXT enables WRITE_TEXT option INFO_IMAGE -# Simplified API options +# added at libpng-1.5.10 +# Turn this off to disable warning about invalid palette index and +# leave the num_palette_max member out of the png structure. + +option CHECK_FOR_INVALID_INDEX +option READ_CHECK_FOR_INVALID_INDEX requires READ CHECK_FOR_INVALID_INDEX +option WRITE_CHECK_FOR_INVALID_INDEX requires WRITE CHECK_FOR_INVALID_INDEX + +# Simplified API options (added at libpng-1.6.0) # Read: option SIMPLIFIED_READ requires SEQUENTIAL_READ READ_TRANSFORMS SETJMP option SIMPLIFIED_READ enables READ_EXPAND READ_16BIT READ_EXPAND_16 diff --git a/scripts/pnglibconf.h.prebuilt b/scripts/pnglibconf.h.prebuilt index 8866f4cf9..fc81bd658 100644 --- a/scripts/pnglibconf.h.prebuilt +++ b/scripts/pnglibconf.h.prebuilt @@ -3,7 +3,7 @@ /* pnglibconf.h - library build configuration */ -/* Libpng 1.6.0beta15 - February 27, 2012 */ +/* Libpng 1.6.0beta15 - March 1, 2012 */ /* Copyright (c) 1998-2012 Glenn Randers-Pehrson */ @@ -41,6 +41,7 @@ #define PNG_bKGD_SUPPORTED #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED #define PNG_CHECK_cHRM_SUPPORTED +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_cHRM_SUPPORTED #define PNG_CONSOLE_IO_SUPPORTED #define PNG_CONVERT_tIME_SUPPORTED @@ -72,6 +73,7 @@ #define PNG_READ_BACKGROUND_SUPPORTED #define PNG_READ_BGR_SUPPORTED #define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_READ_cHRM_SUPPORTED #define PNG_READ_COMPOSITE_NODIV_SUPPORTED #define PNG_READ_COMPRESSED_TEXT_SUPPORTED @@ -149,6 +151,7 @@ #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #define PNG_WRITE_BGR_SUPPORTED #define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_WRITE_cHRM_SUPPORTED #define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED #define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED