diff options
author | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2009-09-24 18:10:49 -0500 |
---|---|---|
committer | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2009-09-24 18:10:49 -0500 |
commit | 134bbe416de32c39a64eb4eb102b6978f57f4ae2 (patch) | |
tree | 678cb01bb1a1fb453b9688150aa4f1cd6aad75cf | |
parent | 3243fea0aceed3601159d2a72651e4aa7bf216f5 (diff) | |
download | libpng-134bbe416de32c39a64eb4eb102b6978f57f4ae2.tar.gz |
[devel] Improve IHDR checking and error reporting
Move redundant IHDR checking into new png_check_IHDR() in png.c
and report all errors found in the IHDR data. Report problems
with width and height separately.
-rw-r--r-- | ANNOUNCE | 6 | ||||
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | png.c | 150 | ||||
-rw-r--r-- | pngget.c | 70 | ||||
-rw-r--r-- | pngpriv.h | 10 | ||||
-rw-r--r-- | pngset.c | 72 |
6 files changed, 196 insertions, 116 deletions
@@ -1,5 +1,5 @@ -Libpng 1.4.0beta82 - September 23, 2009 +Libpng 1.4.0beta82 - September 24, 2009 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -558,7 +558,9 @@ version 1.4.0beta81 [September 23, 2009] Changed all "#if [!]defined(X)" to "if[n]def X" where possible. Eliminated unused png_ptr->row_buf_size -version 1.4.0beta82 [September 23, 2009] +version 1.4.0beta82 [September 24, 2009] + Move redundant IHDR checking into new png_check_IHDR() in png.c + and report all errors found in the IHDR data. version 1.4.0betaN [future] Build shared libraries with -lz and sometimes -lm. @@ -2244,7 +2244,9 @@ version 1.4.0beta81 [September 23, 2009] Changed all "#if [!]defined(X)" to "if[n]def X" where possible. Eliminated unused png_ptr->row_buf_size -version 1.4.0beta82 [September 23, 2009] +version 1.4.0beta82 [September 24, 2009] + Move redundant IHDR checking into new png_check_IHDR() in png.c + and report all errors found in the IHDR data. version 1.4.0betaN [future] Build shared libraries with -lz and sometimes -lm. @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.4.0 [September 23, 2009] + * Last changed in libpng 1.4.0 [September 24, 2009] * Copyright (c) 1998-2009 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.) @@ -546,13 +546,13 @@ png_get_copyright(png_structp png_ptr) #else #ifdef __STDC__ return ((png_charp) PNG_STRING_NEWLINE \ - "libpng version x 1.4.0beta82 - September 23, 2009" PNG_STRING_NEWLINE \ + "libpng version x 1.4.0beta82 - September 24, 2009" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2009 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE); #else - return ((png_charp) "libpng version 1.4.0beta82 - September 23, 2009\ + return ((png_charp) "libpng version 1.4.0beta82 - September 24, 2009\ Copyright (c) 1998-2009 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."); @@ -766,4 +766,148 @@ png_check_cHRM_fixed(png_structp png_ptr, } #endif /* PNG_CHECK_cHRM_SUPPORTED */ #endif /* PNG_cHRM_SUPPORTED */ + +void /* PRIVATE */ +png_check_IHDR(png_structp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + int error = 0; + + /* Check for width and height valid values */ + if (width == 0) + { + png_warning(png_ptr, "Image width is zero in IHDR"); + error = 1; + } + + if (height == 0) + { + png_warning(png_ptr, "Image height is zero in IHDR"); + error = 1; + } + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX) + { + png_warning(png_ptr, "Image width exceeds user limit in IHDR"); + error = 1; + } + + if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX) + { + png_warning(png_ptr, "Image height exceeds user limit in IHDR"); + error = 1; + } + +#else + if (width > PNG_USER_WIDTH_MAX + { + png_warning(png_ptr, "Image width exceeds user limit in IHDR"); + error = 1; + } + + if (height > PNG_USER_HEIGHT_MAX) + { + png_warning(png_ptr, "Image height exceeds user limit in IHDR"); + error = 1; + } +#endif + + if (height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image height in IHDR"); + error = 1; + } + + if ( height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image width in IHDR"); + error = 1; + } + + if ( width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 64 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + png_warning(png_ptr, "Width is too large for libpng to process pixels"); + + /* Check other values */ + if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && + bit_depth != 8 && bit_depth != 16) + { + png_warning(png_ptr, "Invalid bit depth in IHDR"); + error = 1; + } + + if (color_type < 0 || color_type == 1 || + color_type == 5 || color_type > 6) + { + png_warning(png_ptr, "Invalid color type in IHDR"); + error = 1; + } + + if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || + ((color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) + { + png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); + error = 1; + } + + if (interlace_type >= PNG_INTERLACE_LAST) + { + png_warning(png_ptr, "Unknown interlace method in IHDR"); + error = 1; + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Unknown compression method in IHDR"); + error = 1; + } + +#ifdef PNG_MNG_FEATURES_SUPPORTED + /* Accept filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not read a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && + png_ptr->mng_features_permitted) + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); + + if (filter_type != PNG_FILTER_TYPE_BASE) + { + if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && + ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA))) + png_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } + + if (png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) + png_warning(png_ptr, "Invalid filter method in IHDR"); + +#else + if (filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } +#endif + + if (error == 1) + png_error(png_ptr, "Invalid IHDR data"); +} #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.4.0 [September 23, 2009] + * Last changed in libpng 1.4.0 [September 24, 2009] * Copyright (c) 1998-2009 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.) @@ -579,52 +579,44 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr, int *filter_type) { - png_debug1(1, "in %s retrieval function", "IHDR"); - - if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL && - bit_depth != NULL && color_type != NULL) - { - *width = info_ptr->width; - *height = info_ptr->height; - *bit_depth = info_ptr->bit_depth; - if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16) - png_error(png_ptr, "Invalid bit depth"); - - *color_type = info_ptr->color_type; + int test_interlace_type = 0; + int test_compression_type = 0; + int test_filter_type = 0; - if (info_ptr->color_type > 6) - png_error(png_ptr, "Invalid color type"); + png_debug1(1, "in %s retrieval function", "IHDR"); - if (compression_type != NULL) - *compression_type = info_ptr->compression_type; + if (png_ptr == NULL || info_ptr == NULL || width == NULL || + height == NULL || bit_depth == NULL || color_type == NULL) + return (0); - if (filter_type != NULL) - *filter_type = info_ptr->filter_type; + *width = info_ptr->width; + *height = info_ptr->height; + *bit_depth = info_ptr->bit_depth; + *color_type = info_ptr->color_type; - if (interlace_type != NULL) - *interlace_type = info_ptr->interlace_type; + if (compression_type != NULL) + { + *compression_type = info_ptr->compression_type; + test_compression_type=*compression_type; + } - /* Check for potential overflow of rowbytes */ - if (*width == 0 || *width > PNG_UINT_31_MAX) - png_error(png_ptr, "Invalid image width"); + if (filter_type != NULL) + { + *filter_type = info_ptr->filter_type; + test_filter_type=*filter_type; + } - if (*height == 0 || *height > PNG_UINT_31_MAX) - png_error(png_ptr, "Invalid image height"); + if (interlace_type != NULL) + { + *interlace_type = info_ptr->interlace_type; + test_interlace_type=*interlace_type; + } - if (info_ptr->width > (PNG_UINT_32_MAX - >> 3) /* 8-byte RGBA pixels */ - - 64 /* bigrowbuf hack */ - - 1 /* filter byte */ - - 7*8 /* rounding of width to multiple of 8 pixels */ - - 8) /* extra max_pixel_depth pad */ - { - png_warning(png_ptr, - "Width too large for libpng to process image data"); - } + png_check_IHDR (png_ptr, *width, *height, *bit_depth, *color_type, + info_ptr->interlace_type, info_ptr->compression_type, + info_ptr->filter_type); - return (1); - } - return (0); + return (1); } #ifdef PNG_oFFs_SUPPORTED @@ -1,7 +1,7 @@ /* pngpriv.h - private declarations for use inside libpng * - * libpng version 1.4.0beta82 - September 23, 2009 + * libpng version 1.4.0beta82 - September 24, 2009 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2009 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -810,13 +810,19 @@ PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, /* Added at libpng version 1.4.0 */ #ifdef PNG_cHRM_SUPPORTED -PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, +PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, png_fixed_point int_blue_y)); #endif +/* Added at libpng version 1.4.0 */ +PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type)); + #ifdef PNG_cHRM_SUPPORTED #ifdef PNG_CHECK_cHRM_SUPPORTED /* Added at libpng version 1.2.34 and 1.4.0 */ @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.4.0 [September 23, 2009] + * Last changed in libpng 1.4.0 [September 24, 2009] * Copyright (c) 1998-2009 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.) @@ -227,74 +227,8 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, if (png_ptr == NULL || info_ptr == NULL) return; - /* Check for width and height valid values */ - if (width == 0 || height == 0) - png_error(png_ptr, "Image width or height is zero in IHDR"); -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (width > png_ptr->user_width_max || height > png_ptr->user_height_max) - png_error(png_ptr, "image size exceeds user limits in IHDR"); -#else - if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX) - png_error(png_ptr, "image size exceeds user limits in IHDR"); -#endif - if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX) - png_error(png_ptr, "Invalid image size in IHDR"); - if ( width > (PNG_UINT_32_MAX - >> 3) /* 8-byte RGBA pixels */ - - 64 /* bigrowbuf hack */ - - 1 /* filter byte */ - - 7*8 /* rounding of width to multiple of 8 pixels */ - - 8) /* extra max_pixel_depth pad */ - png_warning(png_ptr, "Width is too large for libpng to process pixels"); - - /* Check other values */ - if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && - bit_depth != 8 && bit_depth != 16) - png_error(png_ptr, "Invalid bit depth in IHDR"); - - if (color_type < 0 || color_type == 1 || - color_type == 5 || color_type > 6) - png_error(png_ptr, "Invalid color type in IHDR"); - - if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || - ((color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) - png_error(png_ptr, "Invalid color type/bit depth combination in IHDR"); - - if (interlace_type >= PNG_INTERLACE_LAST) - png_error(png_ptr, "Unknown interlace method in IHDR"); - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - png_error(png_ptr, "Unknown compression method in IHDR"); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - /* Accept filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not read a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted) - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - if (filter_type != PNG_FILTER_TYPE_BASE) - { - if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && - ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA))) - png_error(png_ptr, "Unknown filter method in IHDR"); - if (png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) - png_warning(png_ptr, "Invalid filter method in IHDR"); - } -#else - if (filter_type != PNG_FILTER_TYPE_BASE) - png_error(png_ptr, "Unknown filter method in IHDR"); -#endif + png_check_IHDR (png_ptr, width, height, bit_depth, color_type, + interlace_type, compression_type, filter_type); info_ptr->width = width; info_ptr->height = height; |