diff -r -U 3 libpng-0.95/png.h libpng-0.95p/png.h --- libpng-0.95/png.h Sat Mar 29 04:59:50 1997 +++ libpng-0.95p/png.h Tue Aug 3 21:50:20 2004 @@ -360,6 +360,11 @@ typedef png_info FAR * png_infop; typedef png_info FAR * FAR * png_infopp; +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) +#define PNG_UINT_32_MAX (~((png_uint_32)0)) +#define PNG_SIZE_MAX (~((png_size_t)0)) + /* These describe the color_type field in png_info. */ /* color type masks */ #define PNG_COLOR_MASK_PALETTE 1 @@ -1370,6 +1375,8 @@ PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf)); PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf)); #endif /* PNG_BIG_ENDIAN_GET_SUPPORTED */ +PNG_EXTERN png_uint_32 png_get_uint_31 PNGARG((png_structp png_ptr, + png_bytep buf)); /* Initialize png_ptr struct for reading, and allocate any other memory * (old interface - NOT DLL EXPORTED) */ diff -r -U 3 libpng-0.95/pngconf.h libpng-0.95p/pngconf.h --- libpng-0.95/pngconf.h Sat Mar 29 02:35:00 1997 +++ libpng-0.95p/pngconf.h Tue Aug 3 21:51:25 2004 @@ -239,6 +239,13 @@ #define PNG_WRITE_SWAP_ALPHA_SUPPORTED #define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +#endif +#ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +#endif + /* These are currently experimental features */ #undef PNG_READ_16_TO_8_ACCURATE_SHIFT_SUPPORTED /* very little testing */ #undef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* very little testing */ diff -r -U 3 libpng-0.95/pngpread.c libpng-0.95p/pngpread.c --- libpng-0.95/pngpread.c Sat Mar 29 02:35:18 1997 +++ libpng-0.95p/pngpread.c Tue Aug 3 21:50:21 2004 @@ -131,7 +131,7 @@ } png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_32(chunk_length); + png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER; @@ -449,6 +449,11 @@ png_size_t new_max; png_bytep old_buffer; + if (png_ptr->save_buffer_size > PNG_SIZE_MAX - + (png_ptr->current_buffer_size + 256)) + { + png_error(png_ptr, "Potential overflow of save_buffer"); + } new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; old_buffer = png_ptr->save_buffer; png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, new_max); @@ -491,8 +496,7 @@ } png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_32(chunk_length); - + png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER; diff -r -U 3 libpng-0.95/pngread.c libpng-0.95p/pngread.c --- libpng-0.95/pngread.c Sat Mar 29 02:35:22 1997 +++ libpng-0.95p/pngread.c Tue Aug 3 21:50:21 2004 @@ -155,7 +155,7 @@ png_uint_32 length; png_read_data(png_ptr, chunk_length, 4); - length = png_get_uint_32(chunk_length); + length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); @@ -363,7 +363,7 @@ png_crc_finish(png_ptr, 0); png_read_data(png_ptr, chunk_length, 4); - png_ptr->idat_size = png_get_uint_32(chunk_length); + png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); @@ -539,7 +539,7 @@ do { png_read_data(png_ptr, chunk_length, 4); - length = png_get_uint_32(chunk_length); + length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); diff -r -U 3 libpng-0.95/pngrutil.c libpng-0.95p/pngrutil.c --- libpng-0.95/pngrutil.c Sat Mar 29 05:43:38 1997 +++ libpng-0.95p/pngrutil.c Tue Aug 3 21:50:21 2004 @@ -11,6 +11,14 @@ #define PNG_INTERNAL #include "png.h" +png_uint_32 /* PRIVATE */ +png_get_uint_31(png_structp png_ptr, png_bytep buf) +{ + png_uint_32 i = png_get_uint_32(buf); + if (i > PNG_UINT_31_MAX) + png_error(png_ptr, "PNG unsigned integer out of range.\n"); + return (i); +} #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED /* Grab an unsigned 32-bit integer from a buffer in big endian format. */ png_uint_32 @@ -659,7 +667,8 @@ /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Missing PLTE before tRNS"); } - else if (length > png_ptr->num_palette) + if (length > (png_uint_32)png_ptr->num_palette || + length > 256) { png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); diff -r -U 3 libpng-0.95/pngset.c libpng-0.95p/pngset.c --- libpng-0.95/pngset.c Sat Mar 29 07:07:34 1997 +++ libpng-0.95p/pngset.c Tue Aug 3 21:50:21 2004 @@ -82,6 +82,9 @@ if (info_ptr == NULL) return; + if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX) + png_error(png_ptr, "image size exceeds user limits in IHDR"); + info_ptr->width = width; info_ptr->height = height; info_ptr->bit_depth = (png_byte)bit_depth;