[legacy] Backported new png_decompress_chunk() algorithm from libpng-1.4.1

This commit is contained in:
Glenn Randers-Pehrson 2010-02-01 09:28:01 -06:00
parent 17020e5076
commit eea742c2c5
3 changed files with 134 additions and 68 deletions

View File

@ -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 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. 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 Source files with LF line endings (for Unix/Linux) and with a
"configure" script "configure" script
libpng-1.2.43beta01.tar.xz (LZMA-compressed, recommended) libpng-1.2.43beta02.tar.xz (LZMA-compressed, recommended)
libpng-1.2.43beta01.tar.gz libpng-1.2.43beta02.tar.gz
libpng-1.2.43beta01.tar.bz2 libpng-1.2.43beta02.tar.bz2
Source files with LF line endings (for Unix/Linux) without the Source files with LF line endings (for Unix/Linux) without the
"configure" script "configure" script
libpng-1.2.43beta01-no-config.tar.xz (LZMA-compressed, recommended) libpng-1.2.43beta02-no-config.tar.xz (LZMA-compressed, recommended)
libpng-1.2.43beta01-no-config.tar.gz libpng-1.2.43beta02-no-config.tar.gz
libpng-1.2.43beta01-no-config.tar.bz2 libpng-1.2.43beta02-no-config.tar.bz2
Source files with CRLF line endings (for Windows), without the Source files with CRLF line endings (for Windows), without the
"configure" script "configure" script
lp1243b01.zip lp1243b02.zip
lp1243b01.7z lp1243b02.7z
lp1243b01.tar.bz2 lp1243b02.tar.bz2
Project files Project files
libpng-1.2.43beta01-project-netware.zip libpng-1.2.43beta02-project-netware.zip
libpng-1.2.43beta01-project-wince.zip libpng-1.2.43beta02-project-wince.zip
Other information: Other information:
libpng-1.2.43beta01-README.txt libpng-1.2.43beta02-README.txt
libpng-1.2.43beta01-KNOWNBUGS.txt libpng-1.2.43beta02-KNOWNBUGS.txt
libpng-1.2.43beta01-LICENSE.txt libpng-1.2.43beta02-LICENSE.txt
libpng-1.2.43beta01-Y2K-compliance.txt libpng-1.2.43beta02-Y2K-compliance.txt
libpng-1.2.43beta01-[previous version]-diff.txt libpng-1.2.43beta02-[previous version]-diff.txt
Changes since the last public release (1.2.42): 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 Updated CMakeLists.txt for consistent indentation and to avoid an
unclosed if-statement warning (Philip Lowman). unclosed if-statement warning (Philip Lowman).
Removed "#ifdef PNG_1_0_X / #endif" surrounding Removed "#ifdef PNG_1_0_X / #endif" surrounding
PNG_READ_16_TO_8_SUPPORTED and PNG_READ_GRAY_TO_RGB_SUPPORTED 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, 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. 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 Send comments/corrections/commendations to png-mng-implement at lists.sf.net

View File

@ -2643,13 +2643,17 @@ version 1.2.42rc05 [January 2, 2010]
version 1.2.42 and 1.0.52 [January 3, 2010] version 1.2.42 and 1.0.52 [January 3, 2010]
No changes. 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 Updated CMakeLists.txt for consistent indentation and to avoid an
unclosed if-statement warning (Philip Lowman). unclosed if-statement warning (Philip Lowman).
Removed "#ifdef PNG_1_0_X / #endif" surrounding Removed "#ifdef PNG_1_0_X / #endif" surrounding
PNG_READ_16_TO_8_SUPPORTED and PNG_READ_GRAY_TO_RGB_SUPPORTED 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, 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. 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 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -1,7 +1,7 @@
/* pngrutil.c - utilities to read a PNG file /* 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 * Copyright (c) 1998-2009 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (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) || \ #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
defined(PNG_READ_iCCP_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 * Decompress trailing data in a chunk. The assumption is that chunkdata
* points at an allocated area holding the contents of a chunk with a * points at an allocated area holding the contents of a chunk with a
@ -232,10 +294,21 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
static PNG_CONST char msg[] = "Error decoding compressed chunk"; static PNG_CONST char msg[] = "Error decoding compressed chunk";
png_charp text; png_charp text;
png_size_t text_size; 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) if (comp_type == PNG_COMPRESSION_TYPE_BASE)
{ {
int ret = Z_OK; int ret = Z_OK;
png_size_t buffer_size;
png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_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.avail_in = (uInt)(chunklength - prefix_size);
png_ptr->zstream.next_out = png_ptr->zbuf; 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_size = 0;
text = NULL; text = NULL;
buffer_size = 0;
while (png_ptr->zstream.avail_in) while (png_ptr->zstream.avail_in)
{ {
@ -262,9 +336,10 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
text = (png_charp)png_malloc_warn(png_ptr, text_size); text = (png_charp)png_malloc_warn(png_ptr, text_size);
if (text == NULL) if (text == NULL)
{ {
png_free(png_ptr, png_ptr->chunkdata); png_error(png_ptr,
png_ptr->chunkdata = NULL; "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); png_memcpy(text, png_ptr->chunkdata, prefix_size);
} }
@ -274,62 +349,45 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
/* Copy what we can of the error message into the text chunk */ /* Copy what we can of the error message into the text chunk */
text_size = (png_size_t)(chunklength - text_size = (png_size_t)(chunklength -
(text - png_ptr->chunkdata) - 1); (text - png_ptr->chunkdata) - 1);
if (text_size > png_sizeof(msg)) if (text_size > png_sizeof(msg))
text_size = png_sizeof(msg); text_size = png_sizeof(msg);
png_memcpy(text + prefix_size, msg, text_size); png_memcpy(text + prefix_size, msg, text_size);
buffer_size = text_size;
break; break;
} }
if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
{ {
if (text == NULL) if (text == NULL) /* Initialize the decompression buffer */
{ {
text_size = prefix_size + text_size = expanded_size;
png_ptr->zbuf_size - png_ptr->zstream.avail_out;
text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
if (text == NULL) if (text == NULL)
{ {
png_free(png_ptr, png_ptr->chunkdata);
png_ptr->chunkdata = NULL;
png_error(png_ptr, png_error(png_ptr,
"Not enough memory to decompress chunk."); "Not enough memory to decompress chunk.");
text_size = 0;
break;
} }
png_memcpy(text + prefix_size, png_ptr->zbuf, png_memcpy(text + prefix_size, png_ptr->zbuf,
text_size - prefix_size); text_size - prefix_size);
png_memcpy(text, png_ptr->chunkdata, prefix_size); png_memcpy(text, png_ptr->chunkdata, prefix_size);
*(text + text_size) = 0x00; *(text + text_size) = 0x00;
buffer_size = text_size;
} }
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) if (ret == Z_STREAM_END)
break; break;
else else
{ {
png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
} }
} }
}
if (ret != Z_STREAM_END) if (ret != Z_STREAM_END)
{ {
#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
@ -363,7 +421,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
{ {
png_free(png_ptr, png_ptr->chunkdata); png_free(png_ptr, png_ptr->chunkdata);
png_ptr->chunkdata = NULL; png_ptr->chunkdata = NULL;
png_error(png_ptr, "Not enough memory for text."); png_error(png_ptr, "Not enough memory for text");
} }
png_memcpy(text, png_ptr->chunkdata, prefix_size); png_memcpy(text, png_ptr->chunkdata, prefix_size);
} }