< prev index next >
src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
Print this page
*** 27,38 ****
* 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
* (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
--- 27,38 ----
* 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.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,163 ****
--- 153,166 ----
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,820 ****
--- 814,826 ----
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,851 ****
#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");
}
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");
png_crc_finish(png_ptr, length);
}
else if (chunk_name == png_PLTE)
png_handle_PLTE(png_ptr, info_ptr, length);
--- 831,861 ----
#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->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. 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,3892 ****
filler = 65535;
else
filler = 255;
! # ifdef PNG_FORMAT_AFIRST_SUPPORTED
if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
{
where = PNG_FILLER_BEFORE;
change &= ~PNG_FORMAT_FLAG_AFIRST;
}
else
! # endif
where = PNG_FILLER_AFTER;
png_set_add_alpha(png_ptr, filler, where);
}
--- 3884,3902 ----
filler = 65535;
else
filler = 255;
! #ifdef PNG_FORMAT_AFIRST_SUPPORTED
if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
{
where = PNG_FILLER_BEFORE;
change &= ~PNG_FORMAT_FLAG_AFIRST;
}
else
! #endif
where = PNG_FILLER_AFTER;
png_set_add_alpha(png_ptr, filler, where);
}
*** 3991,4006 ****
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
if ((png_ptr->transformations & PNG_BGR) != 0)
info_format |= PNG_FORMAT_FLAG_BGR;
! # endif
! # ifdef PNG_FORMAT_AFIRST_SUPPORTED
if (do_local_background == 2)
{
if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
info_format |= PNG_FORMAT_FLAG_AFIRST;
}
--- 4001,4016 ----
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
if ((png_ptr->transformations & PNG_BGR) != 0)
info_format |= PNG_FORMAT_FLAG_BGR;
! #endif
! #ifdef PNG_FORMAT_AFIRST_SUPPORTED
if (do_local_background == 2)
{
if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
info_format |= PNG_FORMAT_FLAG_AFIRST;
}
*** 4097,4119 ****
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)
{
png_uint_32 check;
if (row_stride == 0)
! row_stride = PNG_IMAGE_ROW_STRIDE(*image);
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->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
(image->colormap_entries > 0 && colormap != NULL))
{
int result;
--- 4107,4143 ----
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_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_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,4145 ****
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.
*/
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);
else
result =
! png_safe_execute(image, png_image_read_direct, &display);
png_image_free(image);
return result;
}
--- 4149,4171 ----
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.
*/
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);
else
result =
! png_safe_execute(image,
! png_image_read_direct, &display);
png_image_free(image);
return result;
}
*** 4148,4160 ****
--- 4174,4196 ----
"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 >