< prev index next >

src/java.desktop/share/native/libsplashscreen/libpng/pngread.c

Print this page

        

@@ -27,12 +27,12 @@
  * This file is available under and governed by the GNU General Public
  * License version 2 only, as published by the Free Software Foundation.
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.23 [June 9, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer

@@ -153,11 +153,14 @@
 
          png_ptr->mode |= PNG_HAVE_IDAT;
       }
 
       else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+      {
+         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
          png_ptr->mode |= PNG_AFTER_IDAT;
+      }
 
       /* This should be a binary subdivision search or a hash for
        * matching the chunk name rather than a linear search.
        */
       if (chunk_name == png_IHDR)

@@ -811,10 +814,13 @@
    do
    {
       png_uint_32 length = png_read_chunk_header(png_ptr);
       png_uint_32 chunk_name = png_ptr->chunk_name;
 
+      if (chunk_name != png_IDAT)
+         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
       if (chunk_name == png_IEND)
          png_handle_IEND(png_ptr, info_ptr, length);
 
       else if (chunk_name == png_IHDR)
          png_handle_IHDR(png_ptr, info_ptr, length);

@@ -825,27 +831,31 @@
 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
       else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
       {
          if (chunk_name == png_IDAT)
          {
-            if ((length > 0) ||
-                (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
-               png_benign_error(png_ptr, "Too many IDATs found");
+            if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+                || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+               png_benign_error(png_ptr, ".Too many IDATs found");
          }
          png_handle_unknown(png_ptr, info_ptr, length, keep);
          if (chunk_name == png_PLTE)
             png_ptr->mode |= PNG_HAVE_PLTE;
       }
 #endif
 
       else if (chunk_name == png_IDAT)
       {
          /* Zero length IDATs are legal after the last IDAT has been
-          * read, but not after other chunks have been read.
-          */
-         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
-            png_benign_error(png_ptr, "Too many IDATs found");
+          * read, but not after other chunks have been read.  1.6 does not
+          * always read all the deflate data; specifically it cannot be relied
+          * upon to read the Adler32 at the end.  If it doesn't ignore IDAT
+          * chunks which are longer than zero as well:
+          */
+         if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+             || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+            png_benign_error(png_ptr, "..Too many IDATs found");
 
          png_crc_finish(png_ptr, length);
       }
       else if (chunk_name == png_PLTE)
          png_handle_PLTE(png_ptr, info_ptr, length);

@@ -3874,19 +3884,19 @@
                filler = 65535;
 
             else
                filler = 255;
 
-#           ifdef PNG_FORMAT_AFIRST_SUPPORTED
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
                if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
                {
                   where = PNG_FILLER_BEFORE;
                   change &= ~PNG_FORMAT_FLAG_AFIRST;
                }
 
                else
-#           endif
+#endif
                where = PNG_FILLER_AFTER;
 
             png_set_add_alpha(png_ptr, filler, where);
          }
 

@@ -3991,16 +4001,16 @@
          png_error(png_ptr, "png_image_read: alpha channel lost");
 
       if (info_ptr->bit_depth == 16)
          info_format |= PNG_FORMAT_FLAG_LINEAR;
 
-#     ifdef PNG_FORMAT_BGR_SUPPORTED
+#ifdef PNG_FORMAT_BGR_SUPPORTED
          if ((png_ptr->transformations & PNG_BGR) != 0)
             info_format |= PNG_FORMAT_FLAG_BGR;
-#     endif
+#endif
 
-#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
          if (do_local_background == 2)
          {
             if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
                info_format |= PNG_FORMAT_FLAG_AFIRST;
          }

@@ -4097,23 +4107,37 @@
 png_image_finish_read(png_imagep image, png_const_colorp background,
    void *buffer, png_int_32 row_stride, void *colormap)
 {
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
+      /* Check for row_stride overflow.  This check is not performed on the
+       * original PNG format because it may not occur in the output PNG format
+       * and libpng deals with the issues of reading the original.
+       */
+      const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
+
+      if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */
+      {
       png_uint_32 check;
+         const png_uint_32 png_row_stride = image->width * channels;
 
       if (row_stride == 0)
-         row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+            row_stride = (png_int_32)/*SAFE*/png_row_stride;
 
       if (row_stride < 0)
          check = -row_stride;
 
       else
          check = row_stride;
 
-      if (image->opaque != NULL && buffer != NULL &&
-         check >= PNG_IMAGE_ROW_STRIDE(*image))
+         if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
+         {
+            /* Now check for overflow of the image buffer calculation; this
+             * limits the whole image size to 32 bits for API compatibility with
+             * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+             */
+            if (image->height <= 0xFFFFFFFF/png_row_stride)
       {
          if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
             (image->colormap_entries > 0 && colormap != NULL))
          {
             int result;

@@ -4125,21 +4149,23 @@
             display.row_stride = row_stride;
             display.colormap = colormap;
             display.background = background;
             display.local_row = NULL;
 
-            /* Choose the correct 'end' routine; for the color-map case all the
-             * setup has already been done.
+                  /* Choose the correct 'end' routine; for the color-map case
+                   * all the setup has already been done.
              */
             if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
-               result =
-                  png_safe_execute(image, png_image_read_colormap, &display) &&
-                  png_safe_execute(image, png_image_read_colormapped, &display);
+                     result = png_safe_execute(image,
+                                    png_image_read_colormap, &display) &&
+                              png_safe_execute(image,
+                                    png_image_read_colormapped, &display);
 
             else
                result =
-                  png_safe_execute(image, png_image_read_direct, &display);
+                        png_safe_execute(image,
+                              png_image_read_direct, &display);
 
             png_image_free(image);
             return result;
          }
 

@@ -4148,13 +4174,23 @@
                "png_image_finish_read[color-map]: no color-map");
       }
 
       else
          return png_image_error(image,
+                  "png_image_finish_read: image too large");
+         }
+
+         else
+            return png_image_error(image,
             "png_image_finish_read: invalid argument");
    }
 
+      else
+         return png_image_error(image,
+            "png_image_finish_read: row_stride too large");
+   }
+
    else if (image != NULL)
       return png_image_error(image,
          "png_image_finish_read: damaged PNG_IMAGE_VERSION");
 
    return 0;
< prev index next >