From 134c5761fa6fe00b620cfd228e827f08cd2fa65b Mon Sep 17 00:00:00 2001 From: John Bowler Date: Fri, 10 Aug 2012 10:46:45 -0500 Subject: [PATCH] [libpng16] Fix new leak when text compression is disabled. --- contrib/libtests/pngvalid.c | 17 +++++++++----- pngset.c | 2 +- pngwrite.c | 2 -- pngwutil.c | 47 +++++++++++++++++++------------------ 4 files changed, 36 insertions(+), 32 deletions(-) diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c index 7dc5471a5..d691aaac6 100644 --- a/contrib/libtests/pngvalid.c +++ b/contrib/libtests/pngvalid.c @@ -3308,6 +3308,11 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); #ifdef PNG_TEXT_SUPPORTED +# if (defined PNG_READ_zTXt_SUPPORTED) && (defined PNG_WRITE_zTXt_SUPPORTED) +# define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_zTXt +# else +# define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_NONE +# endif { static char key[] = "image name"; /* must be writeable */ size_t pos; @@ -3317,7 +3322,7 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, /* Use a compressed text string to test the correct interaction of text * compression and IDAT compression. */ - text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.compression = TEXT_COMPRESSION; text.key = key; /* Yuck: the text must be writable! */ pos = safecat(copy, sizeof copy, 0, ps->wname); @@ -3375,7 +3380,7 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, /* Use a compressed text string to test the correct interaction of text * compression and IDAT compression. */ - text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.compression = TEXT_COMPRESSION; text.key = key; text.text = comment; text.text_length = (sizeof comment)-1; @@ -3546,7 +3551,7 @@ make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, /* Use a compressed text string to test the correct interaction of text * compression and IDAT compression. */ - text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.compression = TEXT_COMPRESSION; text.key = key; /* Yuck: the text must be writable! */ pos = safecat(copy, sizeof copy, 0, ps->wname); @@ -3646,7 +3651,7 @@ make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, /* Use a compressed text string to test the correct interaction of text * compression and IDAT compression. */ - text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.compression = TEXT_COMPRESSION; text.key = key; text.text = comment; text.text_length = (sizeof comment)-1; @@ -4624,11 +4629,11 @@ standard_check_text(png_const_structp pp, png_const_textp tp, pos = safecat(msg, sizeof msg, pos, ": "); ok = pos; - if (tp->compression != PNG_TEXT_COMPRESSION_zTXt) + if (tp->compression != TEXT_COMPRESSION) { char buf[64]; - sprintf(buf, "compression [%d->%d], ", PNG_TEXT_COMPRESSION_zTXt, + sprintf(buf, "compression [%d->%d], ", TEXT_COMPRESSION, tp->compression); pos = safecat(msg, sizeof msg, pos, buf); } diff --git a/pngset.c b/pngset.c index 6679bdece..7adc1758e 100644 --- a/pngset.c +++ b/pngset.c @@ -1297,7 +1297,7 @@ png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) } # endif -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +# ifdef PNG_WRITE_SUPPORTED if (!(png_ptr->mode & PNG_IS_READ_STRUCT)) { if (png_ptr->zowner != 0) diff --git a/pngwrite.c b/pngwrite.c index 83cc3abde..f7b0f5c50 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -872,9 +872,7 @@ png_write_destroy(png_structrp png_ptr) deflateEnd(&png_ptr->zstream); /* Free our memory. png_free checks NULL for us. */ -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); -#endif png_free(png_ptr, png_ptr->row_buf); #ifdef PNG_WRITE_FILTER_SUPPORTED png_free(png_ptr, png_ptr->prev_row); diff --git a/pngwutil.c b/pngwutil.c index c475745dd..ee80747a6 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -452,6 +452,27 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, } } +/* Clean up (or trim) a linked list of compression buffers. */ +void /* PRIVATE */ +png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) +{ + png_compression_bufferp list = *listp; + + if (list != NULL) + { + *listp = NULL; + + do + { + png_compression_bufferp next = list->next; + + png_free(png_ptr, list); + list = next; + } + while (list != NULL); + } +} + #ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED /* This pair of functions encapsulates the operation of (a) compressing a * text string, and (b) issuing it later as a series of chunk data writes. @@ -480,26 +501,6 @@ png_text_compress_init(compression_state *comp, png_const_bytep input, comp->output_len = 0; } -void /* PRIVATE */ -png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) -{ - png_compression_bufferp list = *listp; - - if (list != NULL) - { - *listp = NULL; - - do - { - png_compression_bufferp next = list->next; - - png_free(png_ptr, list); - list = next; - } - while (list != NULL); - } -} - /* Compress the data in the compression state input */ static int png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, @@ -1025,6 +1026,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, { /* First time. Ensure we have a temporary buffer for compression and * trim the buffer list if it has more than one entry to free memory. + * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been + * created at this point, but the check here is quick and safe. */ if (png_ptr->zbuffer_list == NULL) { @@ -1033,10 +1036,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, png_ptr->zbuffer_list->next = NULL; } -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED else png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); -#endif /* It is a terminal error if we can't claim the zstream. */ if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) @@ -1640,7 +1641,7 @@ png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, compression_state comp; png_debug(1, "in png_write_zTXt"); - PNG_UNUSED(text_len); /* Always use strlen */ + PNG_UNUSED(text_len) /* Always use strlen */ if (compression == PNG_TEXT_COMPRESSION_NONE) {