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