diff --git a/pngget.c b/pngget.c index 9fa2ac079..2d1441c01 100644 --- a/pngget.c +++ b/pngget.c @@ -895,14 +895,15 @@ png_get_user_height_max (png_structp png_ptr) png_uint_32 PNGAPI png_get_chunk_cache_max (png_structp png_ptr) { - return (png_ptr? (png_ptr->user_chunk_cache_max? 0x7fffffffL : - png_ptr->user_chunk_cache_max - 1) : 0); + return (png_ptr? (png_ptr->user_chunk_cache_max? + png_ptr->user_chunk_cache_max - 1 : 0x7fffffffL) : 0); } /* This function was added to libpng 1.4.1 */ png_uint_32 PNGAPI png_get_chunk_malloc_max (png_structp png_ptr) { - return (png_ptr? png_ptr->user_chunk_cache_max : 0); + return (png_ptr? (png_ptr->user_chunk_malloc_max? + png_ptr->user_chunk_malloc_max : 0x7fffffffL) : 0); } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ diff --git a/pngread.c b/pngread.c index 1b3a3f575..b7794200a 100644 --- a/pngread.c +++ b/pngread.c @@ -70,6 +70,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; /* Added at libpng-1.4.0 */ png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; + png_ptr->user_chunk_malloc_max = png_get_chunk_malloc_max(png_ptr); #endif #ifdef PNG_SETJMP_SUPPORTED diff --git a/pngrutil.c b/pngrutil.c index e0222d6e5..741b2c60d 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -210,8 +210,8 @@ png_crc_error(png_structp png_ptr) */ void /* PRIVATE */ png_decompress_chunk(png_structp png_ptr, int comp_type, - png_size_t chunklength, - png_size_t prefix_size, png_size_t *newlength) + png_size_t chunklength, + png_size_t prefix_size, png_size_t *newlength) { static PNG_CONST char msg[] = "Error decoding compressed chunk"; png_charp text; @@ -248,12 +248,12 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, text_size = prefix_size + png_sizeof(msg) + 1; text = (png_charp)png_malloc_warn(png_ptr, text_size); if (text == NULL) - { - png_error(png_ptr, - "Not enough memory to decompress chunk"); - text_size = 0; - break; - } + { + png_error(png_ptr, + "Not enough memory to decompress chunk"); + text_size = 0; + break; + } png_memcpy(text, png_ptr->chunkdata, prefix_size); } @@ -261,9 +261,11 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, /* Copy what we can of the error message into the text chunk */ text_size = (png_size_t)(chunklength - - (text - png_ptr->chunkdata) - 1); + (text - png_ptr->chunkdata) - 1); + if (text_size > png_sizeof(msg)) text_size = png_sizeof(msg); + png_memcpy(text + prefix_size, msg, text_size); buffer_size = text_size; break; @@ -283,9 +285,9 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, text_size = 0; break; } - png_memcpy(text, png_ptr->chunkdata, prefix_size); png_memcpy(text + prefix_size, png_ptr->zbuf, text_size - prefix_size); + png_memcpy(text, png_ptr->chunkdata, prefix_size); *(text + text_size) = 0x00; buffer_size = text_size; } @@ -303,33 +305,49 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, buffer_size = new_text_size; else buffer_size += buffer_size; - } #ifdef PNG_CHUNK_MALLOC_LIMIT_SUPPORTED - if (png_ptr->user_chunk_malloc_max <= buffer_size) - { - png_free(png_ptr, tmp); - png_warning(png_ptr, "No space for decompressed chunk"); - text = NULL; - } + if (buffer_size >= png_ptr->user_chunk_malloc_max - 1) + { + if (new_text_size >= + png_ptr->user_chunk_malloc_max - 1) + { + png_free(png_ptr, tmp); + png_warning(png_ptr, + "No space for decompressed chunk"); + text = NULL; + } + else + { + buffer_size = png_ptr->user_chunk_malloc_max - 1; + text = (png_charp)png_malloc_warn(png_ptr, + buffer_size + 1); + } + } - else - text = (png_charp)png_malloc_warn(png_ptr, - buffer_size + 1); + else + text = (png_charp)png_malloc_warn(png_ptr, + buffer_size + 1); #else - text = (png_charp)png_malloc_warn(png_ptr, - buffer_size + 1); + text = (png_charp)png_malloc_warn(png_ptr, + buffer_size + 1); #endif - if (text == NULL) - { - png_warning(png_ptr, - "Not enough memory to decompress chunk"); - break; - } + if (text == NULL) + { + png_warning(png_ptr, + "Not enough memory to decompress chunk"); + break; + } - png_memcpy(text, tmp, text_size); - png_free(png_ptr, tmp); + png_memcpy(text, tmp, text_size); + png_free(png_ptr, tmp); + } + /* FIX ME: zTXt chunk written by pngtest is 6 bytes too large */ + png_memcpy(text + text_size, png_ptr->zbuf, + (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = 0x00; } } if (ret == Z_STREAM_END)