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