< prev index next >
src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.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.27 [January 5, 2017]
! * 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
--- 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.33 [September 28, 2017]
! * Copyright (c) 1998-2002,2004,2006-2017 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
*** 207,216 ****
--- 207,219 ----
png_calculate_crc(png_ptr, buf + 4, 4);
/* Check to see if chunk name is valid. */
png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+ /* Check for too-large chunk length */
+ png_check_chunk_length(png_ptr, length);
+
#ifdef PNG_IO_STATE_SUPPORTED
png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
#endif
return length;
*** 337,346 ****
--- 340,350 ----
{
buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size));
if (buffer != NULL)
{
+ memset(buffer, 0, new_size); /* just in case */
png_ptr->read_buffer = buffer;
png_ptr->read_buffer_size = new_size;
}
else if (warn < 2) /* else silent */
*** 444,454 ****
if (ret == Z_OK)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
}
! #if ZLIB_VERNUM >= 0x1281 && \
defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
/* Turn off validation of the ADLER32 checksum in IDAT chunks */
ret = inflateValidate(&png_ptr->zstream, 0);
#endif
--- 448,458 ----
if (ret == Z_OK)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
}
! #if ZLIB_VERNUM >= 0x1290 && \
defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
/* Turn off validation of the ADLER32 checksum in IDAT chunks */
ret = inflateValidate(&png_ptr->zstream, 0);
#endif
*** 696,705 ****
--- 700,711 ----
png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
buffer_size));
if (text != NULL)
{
+ memset(text, 0, buffer_size);
+
ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
png_ptr->read_buffer + prefix_size, &lzsize,
text + prefix_size, newlength);
if (ret == Z_STREAM_END)
*** 759,770 ****
else
{
/* inflateReset failed, store the error message */
png_zstream_error(png_ptr, ret);
-
- if (ret == Z_STREAM_END)
ret = PNG_UNEXPECTED_ZLIB_RETURN;
}
}
else if (ret == Z_OK)
--- 765,774 ----
*** 1403,1417 ****
/* Consistent with all the above colorspace handling an obviously *invalid*
* chunk is just ignored, so does not invalidate the color space. An
* alternative is to set the 'invalid' flags at the start of this routine
* and only clear them in they were not set before and all the tests pass.
- * The minimum 'deflate' stream is assumed to be just the 2 byte header and
- * 4 byte checksum. The keyword must be at least one character and there is
- * a terminator (0) byte and the compression method.
*/
! if (length < 9)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "too short");
return;
}
--- 1407,1423 ----
/* Consistent with all the above colorspace handling an obviously *invalid*
* chunk is just ignored, so does not invalidate the color space. An
* alternative is to set the 'invalid' flags at the start of this routine
* and only clear them in they were not set before and all the tests pass.
*/
!
! /* The keyword must be at least one character and there is a
! * terminator (0) byte and the compression method byte, and the
! * 'zlib' datastream is at least 11 bytes.
! */
! if (length < 14)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "too short");
return;
}
*** 1439,1448 ****
--- 1445,1464 ----
read_length = (uInt)length;
png_crc_read(png_ptr, (png_bytep)keyword, read_length);
length -= read_length;
+ /* The minimum 'zlib' stream is assumed to be just the 2 byte header,
+ * 5 bytes minimum 'deflate' stream, and the 4 byte checksum.
+ */
+ if (length < 11)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too short");
+ return;
+ }
+
keyword_length = 0;
while (keyword_length < 80 && keyword_length < read_length &&
keyword[keyword_length] != 0)
++keyword_length;
*** 1457,1467 ****
{
read_length -= keyword_length+2;
if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
{
! Byte profile_header[132];
Byte local_buffer[PNG_INFLATE_BUF_SIZE];
png_alloc_size_t size = (sizeof profile_header);
png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
png_ptr->zstream.avail_in = read_length;
--- 1473,1483 ----
{
read_length -= keyword_length+2;
if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
{
! Byte profile_header[132]={0};
Byte local_buffer[PNG_INFLATE_BUF_SIZE];
png_alloc_size_t size = (sizeof profile_header);
png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
png_ptr->zstream.avail_in = read_length;
*** 1487,1497 ****
png_ptr->color_type) != 0)
{
/* Now read the tag table; a variable size buffer is
* needed at this point, allocate one for the whole
* profile. The header check has already validated
! * that none of these stuff will overflow.
*/
const png_uint_32 tag_count = png_get_uint_32(
profile_header+128);
png_bytep profile = png_read_buffer(png_ptr,
profile_length, 2/*silent*/);
--- 1503,1513 ----
png_ptr->color_type) != 0)
{
/* Now read the tag table; a variable size buffer is
* needed at this point, allocate one for the whole
* profile. The header check has already validated
! * that none of this stuff will overflow.
*/
const png_uint_32 tag_count = png_get_uint_32(
profile_header+128);
png_bytep profile = png_read_buffer(png_ptr,
profile_length, 2/*silent*/);
*** 1594,1616 ****
{
png_ptr->zowner = 0;
return;
}
}
!
! else if (size > 0)
! errmsg = "truncated";
!
! #ifndef __COVERITY__
! else
errmsg = png_ptr->zstream.msg;
- #endif
}
-
/* else png_icc_check_tag_table output an error */
}
-
else /* profile truncated */
errmsg = png_ptr->zstream.msg;
}
else
--- 1610,1624 ----
{
png_ptr->zowner = 0;
return;
}
}
! if (errmsg == NULL)
errmsg = png_ptr->zstream.msg;
}
/* else png_icc_check_tag_table output an error */
}
else /* profile truncated */
errmsg = png_ptr->zstream.msg;
}
else
*** 2035,2044 ****
--- 2043,2115 ----
png_set_bKGD(png_ptr, info_ptr, &background);
}
#endif
+ #ifdef PNG_READ_eXIf_SUPPORTED
+ void /* PRIVATE */
+ png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+ {
+ unsigned int i;
+
+ png_debug(1, "in png_handle_eXIf");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (length < 2)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too short");
+ return;
+ }
+
+ else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ info_ptr->free_me |= PNG_FREE_EXIF;
+
+ info_ptr->eXIf_buf = png_voidcast(png_bytep,
+ png_malloc_warn(png_ptr, length));
+
+ if (info_ptr->eXIf_buf == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ for (i = 0; i < length; i++)
+ {
+ png_byte buf[1];
+ png_crc_read(png_ptr, buf, 1);
+ info_ptr->eXIf_buf[i] = buf[0];
+ if (i == 1 && buf[0] != 'M' && buf[0] != 'I'
+ && info_ptr->eXIf_buf[0] != buf[0])
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
+ png_free(png_ptr, info_ptr->eXIf_buf);
+ info_ptr->eXIf_buf = NULL;
+ return;
+ }
+ }
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
+
+ png_free(png_ptr, info_ptr->eXIf_buf);
+ info_ptr->eXIf_buf = NULL;
+ }
+ #endif
+
#ifdef PNG_READ_hIST_SUPPORTED
void /* PRIVATE */
png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
unsigned int num, i;
*** 2563,2572 ****
--- 2634,2646 ----
png_chunk_error(png_ptr, "missing IHDR");
if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
png_ptr->mode |= PNG_AFTER_IDAT;
+ /* Note, "length" is sufficient here; we won't be adding
+ * a null terminator later.
+ */
buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
if (buffer == NULL)
{
png_crc_finish(png_ptr, length);
*** 2609,2621 ****
if (png_decompress_chunk(png_ptr, length, keyword_length+2,
&uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
{
png_text text;
! /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except
! * for the extra compression type byte and the fact that it isn't
! * necessarily '\0' terminated.
*/
buffer = png_ptr->read_buffer;
buffer[uncompressed_length+(keyword_length+2)] = 0;
text.compression = PNG_TEXT_COMPRESSION_zTXt;
--- 2683,2699 ----
if (png_decompress_chunk(png_ptr, length, keyword_length+2,
&uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
{
png_text text;
! if (png_ptr->read_buffer == NULL)
! errmsg="Read failure in png_handle_zTXt";
! else
! {
! /* It worked; png_ptr->read_buffer now looks like a tEXt chunk
! * except for the extra compression type byte and the fact that
! * it isn't necessarily '\0' terminated.
*/
buffer = png_ptr->read_buffer;
buffer[uncompressed_length+(keyword_length+2)] = 0;
text.compression = PNG_TEXT_COMPRESSION_zTXt;
*** 2627,2636 ****
--- 2705,2715 ----
text.lang_key = NULL;
if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
errmsg = "insufficient memory";
}
+ }
else
errmsg = png_ptr->zstream.msg;
}
*** 3001,3020 ****
switch (png_ptr->user_chunk_cache_max)
{
case 2:
png_ptr->user_chunk_cache_max = 1;
png_chunk_benign_error(png_ptr, "no space in chunk cache");
! /* FALL THROUGH */
case 1:
/* NOTE: prior to 1.6.0 this case resulted in an unknown critical
* chunk being skipped, now there will be a hard error below.
*/
break;
default: /* not at limit */
--(png_ptr->user_chunk_cache_max);
! /* FALL THROUGH */
case 0: /* no limit */
# endif /* USER_LIMITS */
/* Here when the limit isn't reached or when limits are compiled
* out; store the chunk.
*/
--- 3080,3099 ----
switch (png_ptr->user_chunk_cache_max)
{
case 2:
png_ptr->user_chunk_cache_max = 1;
png_chunk_benign_error(png_ptr, "no space in chunk cache");
! /* FALLTHROUGH */
case 1:
/* NOTE: prior to 1.6.0 this case resulted in an unknown critical
* chunk being skipped, now there will be a hard error below.
*/
break;
default: /* not at limit */
--(png_ptr->user_chunk_cache_max);
! /* FALLTHROUGH */
case 0: /* no limit */
# endif /* USER_LIMITS */
/* Here when the limit isn't reached or when limits are compiled
* out; store the chunk.
*/
*** 3061,3084 ****
*
* ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
*/
void /* PRIVATE */
! png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
{
int i;
png_debug(1, "in png_check_chunk_name");
for (i=1; i<=4; ++i)
{
! int c = chunk_name & 0xff;
if (c < 65 || c > 122 || (c > 90 && c < 97))
png_chunk_error(png_ptr, "invalid chunk type");
! chunk_name >>= 8;
}
}
/* Combines the row recently read in with the existing pixels in the row. This
* routine takes care of alpha and transparency if requested. This routine also
--- 3140,3201 ----
*
* ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
*/
void /* PRIVATE */
! png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name)
{
int i;
+ png_uint_32 cn=chunk_name;
png_debug(1, "in png_check_chunk_name");
for (i=1; i<=4; ++i)
{
! int c = cn & 0xff;
if (c < 65 || c > 122 || (c > 90 && c < 97))
png_chunk_error(png_ptr, "invalid chunk type");
! cn >>= 8;
! }
! }
!
! void /* PRIVATE */
! png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length)
! {
! png_alloc_size_t limit = PNG_UINT_31_MAX;
!
! # ifdef PNG_SET_USER_LIMITS_SUPPORTED
! if (png_ptr->user_chunk_malloc_max > 0 &&
! png_ptr->user_chunk_malloc_max < limit)
! limit = png_ptr->user_chunk_malloc_max;
! # elif PNG_USER_CHUNK_MALLOC_MAX > 0
! if (PNG_USER_CHUNK_MALLOC_MAX < limit)
! limit = PNG_USER_CHUNK_MALLOC_MAX;
! # endif
! if (png_ptr->chunk_name == png_IDAT)
! {
! png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
! size_t row_factor =
! (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1)
! + 1 + (png_ptr->interlaced? 6: 0));
! if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
! idat_limit=PNG_UINT_31_MAX;
! else
! idat_limit = png_ptr->height * row_factor;
! row_factor = row_factor > 32566? 32566 : row_factor;
! idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */
! idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX;
! limit = limit < idat_limit? idat_limit : limit;
! }
!
! if (length > limit)
! {
! png_debug2(0," length = %lu, limit = %lu",
! (unsigned long)length,(unsigned long)limit);
! png_chunk_error(png_ptr, "chunk data is too large");
}
}
/* Combines the row recently read in with the existing pixels in the row. This
* routine takes care of alpha and transparency if requested. This routine also
*** 3403,3413 ****
/* There is a possibility of a partial copy at the end here; this
* slows the code down somewhat.
*/
do
{
! dp[0] = sp[0], dp[1] = sp[1];
if (row_width <= bytes_to_jump)
return;
sp += bytes_to_jump;
--- 3520,3530 ----
/* There is a possibility of a partial copy at the end here; this
* slows the code down somewhat.
*/
do
{
! dp[0] = sp[0]; dp[1] = sp[1];
if (row_width <= bytes_to_jump)
return;
sp += bytes_to_jump;
*** 3424,3434 ****
/* This can only be the RGB case, so each copy is exactly one
* pixel and it is not necessary to check for a partial copy.
*/
for (;;)
{
! dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
if (row_width <= bytes_to_jump)
return;
sp += bytes_to_jump;
--- 3541,3551 ----
/* This can only be the RGB case, so each copy is exactly one
* pixel and it is not necessary to check for a partial copy.
*/
for (;;)
{
! dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2];
if (row_width <= bytes_to_jump)
return;
sp += bytes_to_jump;
*** 3913,3923 ****
#endif
/* Find the best predictor, the least of pa, pb, pc favoring the earlier
* ones in the case of a tie.
*/
! if (pb < pa) pa = pb, a = b;
if (pc < pa) a = c;
/* Calculate the current pixel in a, and move the previous row pixel to c
* for the next time round the loop
*/
--- 4030,4043 ----
#endif
/* Find the best predictor, the least of pa, pb, pc favoring the earlier
* ones in the case of a tie.
*/
! if (pb < pa)
! {
! pa = pb; a = b;
! }
if (pc < pa) a = c;
/* Calculate the current pixel in a, and move the previous row pixel to c
* for the next time round the loop
*/
*** 3965,3975 ****
pa = p < 0 ? -p : p;
pb = pc < 0 ? -pc : pc;
pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#endif
! if (pb < pa) pa = pb, a = b;
if (pc < pa) a = c;
a += *row;
*row++ = (png_byte)a;
}
--- 4085,4098 ----
pa = p < 0 ? -p : p;
pb = pc < 0 ? -pc : pc;
pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#endif
! if (pb < pa)
! {
! pa = pb; a = b;
! }
if (pc < pa) a = c;
a += *row;
*row++ = (png_byte)a;
}
< prev index next >