[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;