summaryrefslogtreecommitdiff
path: root/pngrutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'pngrutil.c')
-rw-r--r--pngrutil.c126
1 files changed, 84 insertions, 42 deletions
diff --git a/pngrutil.c b/pngrutil.c
index 352910dd1..fe230c048 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 [January 27, 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.)
@@ -226,8 +226,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;
@@ -236,6 +236,8 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
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 +245,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 +264,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 +277,101 @@ 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 = (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;
+ buffer_size = text_size;
}
- else
+ else /* Enlarge the decompression buffer */
{
- png_charp tmp;
+ png_charp tmp = text;
+ png_size_t new_text_size;
- 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)
+ new_text_size = text_size + png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out;
+
+ if (new_text_size > buffer_size)
{
- 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..");
+ if (png_ptr->zstream.avail_out)
+ buffer_size = new_text_size;
+ else
+ buffer_size += buffer_size;
+
+ text = (png_charp)png_malloc_warn(png_ptr,
+ buffer_size + 1);
+
+ 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);
- 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;
+ /* 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)
+ break;
+
+ else
+ {
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
}
+
+ if (text != NULL && buffer_size > text_size)
+ {
+ /* Reduce text allocation to actual size */
+ png_charp tmp;
+
+ tmp = text;
+ text = (png_charp)png_malloc_warn(png_ptr,
+ (png_uint_32)(text_size));
+
+ if (text == NULL)
+ text = tmp;
+
+ else
+ {
+ png_memcpy(text, tmp, text_size + 1);
+ png_free(png_ptr, tmp);
+ }
+
+ }
+
if (ret != Z_STREAM_END)
{
#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
@@ -360,11 +402,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;