Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions pngrutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,7 @@ png_handle_iCCP(png_struct *png_ptr, png_info *info_ptr, png_uint_32 length)
{
const char *errmsg = NULL; /* error message output, or no error */
int finished = 0; /* crc checked */
int ret; /* zlib status of the final inflate call */

png_debug(1, "in png_handle_iCCP");

Expand Down Expand Up @@ -1421,7 +1422,7 @@ png_handle_iCCP(png_struct *png_ptr, png_info *info_ptr, png_uint_32 length)
size = profile_length - (sizeof profile_header)
- 12 * tag_count;

(void)png_inflate_read(png_ptr, local_buffer,
ret = png_inflate_read(png_ptr, local_buffer,
(sizeof local_buffer), &length,
profile + (sizeof profile_header) +
12 * tag_count, &size, 1/*finish*/);
Expand All @@ -1431,7 +1432,7 @@ png_handle_iCCP(png_struct *png_ptr, png_info *info_ptr, png_uint_32 length)
errmsg = "extra compressed data";

/* But otherwise allow extra data: */
else if (size == 0)
else if (ret == Z_STREAM_END && size == 0)
{
if (length > 0)
{
Expand Down Expand Up @@ -1481,6 +1482,16 @@ png_handle_iCCP(png_struct *png_ptr, png_info *info_ptr, png_uint_32 length)
return handled_ok;
}
}
else if (size == 0)
{
/* The LZ stream produced more output
* than the declared profile length;
* accepting it would silently truncate
* the profile.
*/
errmsg = "decompressed data exceeds "
"declared profile length";
}
if (errmsg == NULL)
errmsg = png_ptr->zstream.msg;
}
Expand Down Expand Up @@ -3232,7 +3243,7 @@ read_chunks[PNG_INDEX_unknown] =
/* Allocates 'length+1'; checked in the handler */
# define CDtIME 7U, 7U, 0, hIHDR, 0
# define CDacTL 8U, 8U, hIDAT, hIHDR, 0
# define CDfcTL 25U, 26U, 0, hIHDR, 1
# define CDfcTL 26U, 26U, 0, hIHDR, 1
# define CDfdAT Limit, 4U, hIDAT, hIHDR, 1
/* Supported chunks from PNG extensions 1.5.0, NYI so limit */
# define CDoFFs 9U, 9U, hIDAT, hIHDR, 0
Expand Down
13 changes: 13 additions & 0 deletions pngset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,19 @@ png_set_tRNS(png_struct *png_ptr, png_info *info_ptr,

return;

if (num_trans < 0 || num_trans > PNG_MAX_PALETTE_LENGTH)
{
/* num_trans outside the valid range would be truncated by the
* png_uint_16 assignment below, and the PNG_INFO_tRNS flag would be
* set while trans_alpha is NULL, which leads to a NULL dereference
* in png_write_info (PNG_INVERT_ALPHA) and to an inconsistent state
* visible through png_get_tRNS.
*/
png_warning(png_ptr, "Invalid num_trans in png_set_tRNS");

return;
}

if (trans_alpha != NULL)
{
/* Snapshot the caller's trans_alpha before freeing, in case it
Expand Down
10 changes: 10 additions & 0 deletions pngwutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,16 @@ png_write_eXIf(png_struct *png_ptr, png_byte *exif, int num_exif)

png_debug(1, "in png_write_eXIf");

if (num_exif < 0)
{
/* num_exif is signed in the API; a negative value would wrap into a
* huge chunk length field and corrupt the output stream.
*/
png_warning(png_ptr, "Invalid eXIf chunk length");

return;
}

png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif));

for (i = 0; i < num_exif; i++)
Expand Down