[libpng16] If benign errors are disabled use maximum window on ancillary
inflate. This works round a bug introduced in 1.5.4 where compressed ancillary
chunks could end up with a too-small windowBits value in the deflate
header.
diff --git a/ANNOUNCE b/ANNOUNCE
index f91b5e4..8ab4058 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
-Libpng 1.6.0beta17 - March 9, 2012
+Libpng 1.6.0beta17 - March 10, 2012
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.
@@ -286,13 +286,17 @@
If the call to deflateInit2() is wrong a png_warning will be issued
(in fact this is harmless, but the PNG data produced may be sub-optimal).
-Version 1.6.0beta17 [March 9, 2012]
+Version 1.6.0beta17 [March 10, 2012]
Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition.
Reject all iCCP chunks after the first, even if the first one is invalid.
Deflate/inflate was reworked to move common zlib calls into single
functions [rw]util.c. A new shared keyword check routine was also added
and the 'zbuf' is no longer allocated on progressive read. It is now
possible to call png_inflate() incrementally.
+ If benign errors are disabled use maximum window on ancilliary inflate.
+ This works round a bug introduced in 1.5.4 where compressed ancillary
+ chunks could end up with a too-small windowBits value in the deflate
+ header.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
diff --git a/CHANGES b/CHANGES
index 080a0d7..9719603 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4037,13 +4037,17 @@
If the call to deflateInit2() is wrong a png_warning will be issued
(in fact this is harmless, but the PNG data produced may be sub-optimal).
-Version 1.6.0beta17 [March 9, 2012]
+Version 1.6.0beta17 [March 10, 2012]
Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition.
Reject all iCCP chunks after the first, even if the first one is invalid.
Deflate/inflate was reworked to move common zlib calls into single
functions [rw]util.c. A new shared keyword check routine was also added
and the 'zbuf' is no longer allocated on progressive read. It is now
possible to call png_inflate() incrementally.
+ If benign errors are disabled use maximum window on ancilliary inflate.
+ This works round a bug introduced in 1.5.4 where compressed ancillary
+ chunks could end up with a too-small windowBits value in the deflate
+ header.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
diff --git a/pngrutil.c b/pngrutil.c
index 2befd4a..981a1bb 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -326,7 +326,7 @@
* chunk apparently owns the stream. Prior to release it does a png_error.
*/
static int
-png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
+png_inflate_claim(png_structrp png_ptr, png_uint_32 owner, int window_bits)
{
if (png_ptr->zowner != 0)
{
@@ -373,9 +373,10 @@
if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
{
# if ZLIB_VERNUM < 0x1240
+ PNG_UNUSED(window_bits)
ret = inflateReset(&png_ptr->zstream);
# else
- ret = inflateReset2(&png_ptr->zstream, 0/*use stream windowBits*/);
+ ret = inflateReset2(&png_ptr->zstream, window_bits);
# endif
}
@@ -384,7 +385,7 @@
# if ZLIB_VERNUM < 0x1240
ret = inflateInit(&png_ptr->zstream);
# else
- ret = inflateInit2(&png_ptr->zstream, 0/*use stream windowBits*/);
+ ret = inflateInit2(&png_ptr->zstream, window_bits);
# endif
if (ret == Z_OK)
@@ -571,8 +572,14 @@
if (limit < *newlength)
*newlength = limit;
- /* Now try to claim the stream */
- ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);
+ /* Now try to claim the stream; the 'warn' setting causes zlib to be told
+ * to use the maximum window size during inflate; this hides errors in the
+ * deflate header window bits value which is used if '0' is passed. In
+ * fact this only has an effect with zlib versions 1.2.4 and later - see
+ * the comments in png_inflate_claim above.
+ */
+ ret = png_inflate_claim(png_ptr, png_ptr->chunk_name,
+ png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN ? 15 : 0);
if (ret == Z_OK)
{
@@ -584,11 +591,14 @@
if (ret == Z_STREAM_END)
{
-#if 1
+ /* Use 'inflateReset' here, not 'inflateReset2' because this
+ * preserves the previously decided window size (otherwise it would
+ * be necessary to store the previous window size.) In practice
+ * this doesn't matter anyway, because png_inflate will call inflate
+ * with Z_FINISH in almost all cases, so the window will not be
+ * maintained.
+ */
if (inflateReset(&png_ptr->zstream) == Z_OK)
-#else
- if (inflateReset2(&png_ptr->zstream, 0/*from stream*/) == Z_OK)
-#endif
{
/* Because of the limit checks above we know that the new,
* expanded, size will fit in a size_t (let alone an
@@ -3884,7 +3894,11 @@
}
/* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the
- * process.
+ * process. If the LZ stream is truncated the sequential reader will
+ * terminally damage the stream, above, by reading the chunk header of the
+ * following chunk (it then exits with png_error).
+ *
+ * TODO: deal more elegantly with truncated IDAT lists.
*/
ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
@@ -4336,8 +4350,12 @@
png_free(png_ptr, buffer);
}
- /* Finally claim the zstream for the inflate of the IDAT data. */
- if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)
+ /* Finally claim the zstream for the inflate of the IDAT data, use the bits
+ * value from the stream (note that this will result in a fatal error if the
+ * IDAT stream has a bogus deflate header window_bits value, but this should
+ * not be happening any longer!)
+ */
+ if (png_inflate_claim(png_ptr, png_IDAT, 0) != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg);
png_ptr->flags |= PNG_FLAG_ROW_INIT;