From eea742c2c5063754e76f42b81c4314659157c16d Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Mon, 1 Feb 2010 09:28:01 -0600 Subject: [PATCH] [legacy] Backported new png_decompress_chunk() algorithm from libpng-1.4.1 --- ANNOUNCE | 40 +++++++------- CHANGES | 6 ++- pngrutil.c | 156 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 134 insertions(+), 68 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index 50ce29e1..77ff55e4 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.2.43beta01 - January 14, 2010 +Libpng 1.2.43beta02 - February 1, 2010 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. @@ -9,46 +9,50 @@ Files available for download: Source files with LF line endings (for Unix/Linux) and with a "configure" script - libpng-1.2.43beta01.tar.xz (LZMA-compressed, recommended) - libpng-1.2.43beta01.tar.gz - libpng-1.2.43beta01.tar.bz2 + libpng-1.2.43beta02.tar.xz (LZMA-compressed, recommended) + libpng-1.2.43beta02.tar.gz + libpng-1.2.43beta02.tar.bz2 Source files with LF line endings (for Unix/Linux) without the "configure" script - libpng-1.2.43beta01-no-config.tar.xz (LZMA-compressed, recommended) - libpng-1.2.43beta01-no-config.tar.gz - libpng-1.2.43beta01-no-config.tar.bz2 + libpng-1.2.43beta02-no-config.tar.xz (LZMA-compressed, recommended) + libpng-1.2.43beta02-no-config.tar.gz + libpng-1.2.43beta02-no-config.tar.bz2 Source files with CRLF line endings (for Windows), without the "configure" script - lp1243b01.zip - lp1243b01.7z - lp1243b01.tar.bz2 + lp1243b02.zip + lp1243b02.7z + lp1243b02.tar.bz2 Project files - libpng-1.2.43beta01-project-netware.zip - libpng-1.2.43beta01-project-wince.zip + libpng-1.2.43beta02-project-netware.zip + libpng-1.2.43beta02-project-wince.zip Other information: - libpng-1.2.43beta01-README.txt - libpng-1.2.43beta01-KNOWNBUGS.txt - libpng-1.2.43beta01-LICENSE.txt - libpng-1.2.43beta01-Y2K-compliance.txt - libpng-1.2.43beta01-[previous version]-diff.txt + libpng-1.2.43beta02-README.txt + libpng-1.2.43beta02-KNOWNBUGS.txt + libpng-1.2.43beta02-LICENSE.txt + libpng-1.2.43beta02-Y2K-compliance.txt + libpng-1.2.43beta02-[previous version]-diff.txt Changes since the last public release (1.2.42): -version 1.2.43beta01 [January 14, 2010] +version 1.2.43beta01 [January 27, 2010] Updated CMakeLists.txt for consistent indentation and to avoid an unclosed if-statement warning (Philip Lowman). Removed "#ifdef PNG_1_0_X / #endif" surrounding PNG_READ_16_TO_8_SUPPORTED and PNG_READ_GRAY_TO_RGB_SUPPORTED in pngconf.h. These were added in libpng-1.2.41beta08 and libpng-1.0.51, which introduced a binary incompatibility with libpng-1.0.50. + Backported new png_decompress_chunk() algorithm from libpng-1.4.1 + +version 1.2.43beta02 [February 1, 2010] + Backported two-pass png_decompress_chunk() algorithm from libpng-1.4.1 Send comments/corrections/commendations to png-mng-implement at lists.sf.net diff --git a/CHANGES b/CHANGES index 244688f8..b110c4b0 100644 --- a/CHANGES +++ b/CHANGES @@ -2643,13 +2643,17 @@ version 1.2.42rc05 [January 2, 2010] version 1.2.42 and 1.0.52 [January 3, 2010] No changes. -version 1.2.43beta01 [January 14, 2010] +version 1.2.43beta01 [January 27, 2010] Updated CMakeLists.txt for consistent indentation and to avoid an unclosed if-statement warning (Philip Lowman). Removed "#ifdef PNG_1_0_X / #endif" surrounding PNG_READ_16_TO_8_SUPPORTED and PNG_READ_GRAY_TO_RGB_SUPPORTED in pngconf.h. These were added in libpng-1.2.41beta08 and libpng-1.0.51, which introduced a binary incompatibility with libpng-1.0.50. + Backported new png_decompress_chunk() algorithm from libpng-1.4.1 + +version 1.2.43beta02 [February 1, 2010] + Backported two-pass png_decompress_chunk() algorithm from libpng-1.4.1 Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/pngrutil.c b/pngrutil.c index 352910dd..10ff75e4 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.2.41 [December 3, 2009] + * Last changed in libpng 1.2.43 [February 1, 2010] * 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.) @@ -217,6 +217,68 @@ png_crc_error(png_structp png_ptr) #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ defined(PNG_READ_iCCP_SUPPORTED) +png_size_t +png_measure_decompressed_chunk(png_structp png_ptr, int comp_type, + png_size_t chunklength, png_size_t prefix_size) +{ + png_charp text; + png_charp test = "X"; + png_size_t text_size = 0; + + if (comp_type == PNG_COMPRESSION_TYPE_BASE) + { + int ret = Z_OK; + + png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size); + png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + text = NULL; + + while (png_ptr->zstream.avail_in) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + break; + } + if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) + { + if (text == NULL) /* Initialize the decompression buffer */ + { + text_size = prefix_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out; + + text=test; + } + else /* Enlarge the decompression buffer */ + { + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; +#ifdef PNG_CHUNK_MALLOC_LIMIT_SUPPORTED + if (text_size >= png_ptr->user_chunk_malloc_max - 1) + return 0; +#endif + } + } + if (ret == Z_STREAM_END) + break; + + else + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + } + return text_size; +} + /* * Decompress trailing data in a chunk. The assumption is that chunkdata * points at an allocated area holding the contents of a chunk with a @@ -226,16 +288,27 @@ 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; png_size_t text_size; + png_size_t expanded_size; + + expanded_size= png_measure_decompressed_chunk(png_ptr, comp_type, + chunklength, prefix_size); + if (expanded_size == 0) + { + *newlength=0; + return; + } if (comp_type == PNG_COMPRESSION_TYPE_BASE) { int ret = Z_OK; + png_size_t buffer_size; + png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size); png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); png_ptr->zstream.next_out = png_ptr->zbuf; @@ -243,6 +316,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, text_size = 0; text = NULL; + buffer_size = 0; while (png_ptr->zstream.avail_in) { @@ -261,11 +335,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_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_error(png_ptr, "Not enough memory to decompress chunk"); - } + { + png_error(png_ptr, + "Not enough memory to decompress chunk"); + text_size = 0; + break; + } png_memcpy(text, png_ptr->chunkdata, prefix_size); } @@ -273,63 +348,46 @@ 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; } if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) { - if (text == NULL) + if (text == NULL) /* Initialize the decompression buffer */ { - text_size = prefix_size + - png_ptr->zbuf_size - png_ptr->zstream.avail_out; + text_size = expanded_size; + text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); if (text == NULL) { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; png_error(png_ptr, "Not enough memory to decompress chunk."); + text_size = 0; + break; } png_memcpy(text + prefix_size, png_ptr->zbuf, text_size - prefix_size); png_memcpy(text, png_ptr->chunkdata, prefix_size); *(text + text_size) = 0x00; - } - else - { - png_charp tmp; - - tmp = text; - text = (png_charp)png_malloc_warn(png_ptr, - (png_uint_32)(text_size + - png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); - if (text == NULL) - { - png_free(png_ptr, tmp); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_error(png_ptr, - "Not enough memory to decompress chunk.."); - } - png_memcpy(text, tmp, text_size); - png_free(png_ptr, tmp); - 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) - break; - else - { - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + buffer_size = text_size; } } + if (ret == Z_STREAM_END) + break; + + else + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } } + if (ret != Z_STREAM_END) { #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) @@ -360,11 +418,11 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, { text = (png_charp)png_malloc_warn(png_ptr, text_size+1); if (text == NULL) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_error(png_ptr, "Not enough memory for text."); - } + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_error(png_ptr, "Not enough memory for text"); + } png_memcpy(text, png_ptr->chunkdata, prefix_size); } *(text + text_size) = 0x00;