| Index: third_party/libpng/pngpread.c
|
| diff --git a/third_party/libpng/pngpread.c b/third_party/libpng/pngpread.c
|
| index 52f41a20c51186f1c7e1fe1b94b902afd66b998c..48608f6a194224af57e078a5d48761e38c60f1e1 100644
|
| --- a/third_party/libpng/pngpread.c
|
| +++ b/third_party/libpng/pngpread.c
|
| @@ -1,7 +1,7 @@
|
|
|
| /* pngpread.c - read a png file in push mode
|
| *
|
| - * Last changed in libpng 1.2.43 [February 25, 2010]
|
| + * Last changed in libpng 1.2.44 [June 26, 2010]
|
| * Copyright (c) 1998-2010 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.)
|
| @@ -783,8 +783,7 @@ png_push_read_IDAT(png_structp png_ptr)
|
|
|
| png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
|
|
|
| - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
|
| - png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
|
| + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
|
|
|
| png_ptr->idat_size -= save_size;
|
| png_ptr->buffer_size -= save_size;
|
| @@ -807,8 +806,7 @@ png_push_read_IDAT(png_structp png_ptr)
|
| save_size = png_ptr->current_buffer_size;
|
|
|
| png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
|
| - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
|
| - png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
|
| + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
|
|
|
| png_ptr->idat_size -= save_size;
|
| png_ptr->buffer_size -= save_size;
|
| @@ -833,62 +831,101 @@ void /* PRIVATE */
|
| png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
|
| png_size_t buffer_length)
|
| {
|
| - int ret;
|
| -
|
| - if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
|
| - png_error(png_ptr, "Extra compression data");
|
| + /* The caller checks for a non-zero buffer length. */
|
| + if (!(buffer_length > 0) || buffer == NULL)
|
| + png_error(png_ptr, "No IDAT data (internal error)");
|
|
|
| + /* This routine must process all the data it has been given
|
| + * before returning, calling the row callback as required to
|
| + * handle the uncompressed results.
|
| + */
|
| png_ptr->zstream.next_in = buffer;
|
| png_ptr->zstream.avail_in = (uInt)buffer_length;
|
| - for (;;)
|
| +
|
| + /* Keep going until the decompressed data is all processed
|
| + * or the stream marked as finished.
|
| + */
|
| + while (png_ptr->zstream.avail_in > 0 &&
|
| + !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
|
| {
|
| - ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
|
| - if (ret != Z_OK)
|
| + int ret;
|
| + /* We have data for zlib, but we must check that zlib
|
| + * has somewhere to put the results. It doesn't matter
|
| + * if we don't expect any results -- it may be the input
|
| + * data is just the LZ end code.
|
| + */
|
| + if (!(png_ptr->zstream.avail_out > 0))
|
| {
|
| - if (ret == Z_STREAM_END)
|
| - {
|
| - if (png_ptr->zstream.avail_in)
|
| - png_error(png_ptr, "Extra compressed data");
|
| -
|
| - if (!(png_ptr->zstream.avail_out))
|
| - {
|
| - png_push_process_row(png_ptr);
|
| - }
|
| + png_ptr->zstream.avail_out =
|
| + (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
|
| + png_ptr->iwidth) + 1;
|
| + png_ptr->zstream.next_out = png_ptr->row_buf;
|
| + }
|
|
|
| - png_ptr->mode |= PNG_AFTER_IDAT;
|
| - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
|
| - break;
|
| - }
|
| - else if (ret == Z_BUF_ERROR)
|
| - break;
|
| + /* Using Z_SYNC_FLUSH here means that an unterminated
|
| + * LZ stream can still be handled (a stream with a missing
|
| + * end code), otherwise (Z_NO_FLUSH) a future zlib
|
| + * implementation might defer output and, therefore,
|
| + * change the current behavior. (See comments in inflate.c
|
| + * for why this doesn't happen at present with zlib 1.2.5.)
|
| + */
|
| + ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
|
|
|
| + /* Check for any failure before proceeding. */
|
| + if (ret != Z_OK && ret != Z_STREAM_END)
|
| + {
|
| + /* Terminate the decompression. */
|
| + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
|
| + /* This may be a truncated stream (missing or
|
| + * damaged end code). Treat that as a warning.
|
| + */
|
| + if (png_ptr->row_number >= png_ptr->num_rows ||
|
| + png_ptr->pass > 6)
|
| + png_warning(png_ptr, "Truncated compressed data in IDAT");
|
| else
|
| - png_error(png_ptr, "Decompression Error");
|
| + png_error(png_ptr, "Decompression error in IDAT");
|
| +
|
| + /* Skip the check on unprocessed input */
|
| + return;
|
| }
|
| - if (!(png_ptr->zstream.avail_out))
|
| +
|
| + /* Did inflate output any data? */
|
| + if (png_ptr->zstream.next_out != png_ptr->row_buf)
|
| {
|
| - if ((
|
| -#ifdef PNG_READ_INTERLACING_SUPPORTED
|
| - png_ptr->interlaced && png_ptr->pass > 6) ||
|
| - (!png_ptr->interlaced &&
|
| -#endif
|
| - png_ptr->row_number == png_ptr->num_rows))
|
| + /* Is this unexpected data after the last row?
|
| + * If it is, artificially terminate the LZ output
|
| + * here.
|
| + */
|
| + if (png_ptr->row_number >= png_ptr->num_rows ||
|
| + png_ptr->pass > 6)
|
| {
|
| - if (png_ptr->zstream.avail_in)
|
| - png_warning(png_ptr, "Too much data in IDAT chunks");
|
| + /* Extra data. */
|
| + png_warning(png_ptr, "Extra compressed data in IDAT");
|
| png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
|
| - break;
|
| + /* Do no more processing; skip the unprocessed
|
| + * input check below.
|
| + */
|
| + return;
|
| }
|
| - png_push_process_row(png_ptr);
|
| - png_ptr->zstream.avail_out =
|
| - (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
|
| - png_ptr->iwidth) + 1;
|
| - png_ptr->zstream.next_out = png_ptr->row_buf;
|
| +
|
| + /* Do we have a complete row? */
|
| + if (png_ptr->zstream.avail_out == 0)
|
| + png_push_process_row(png_ptr);
|
| }
|
|
|
| else
|
| break;
|
| + /* And check for the end of the stream. */
|
| + if (ret == Z_STREAM_END)
|
| + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
|
| }
|
| +
|
| + /* All the data should have been processed, if anything
|
| + * is left at this point we have bytes of IDAT data
|
| + * after the zlib end code.
|
| + */
|
| + if (png_ptr->zstream.avail_in > 0)
|
| + png_warning(png_ptr, "Extra compression data");
|
| }
|
|
|
| void /* PRIVATE */
|
|
|