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
14 changes: 10 additions & 4 deletions pngpread.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,16 @@ png_push_read_chunk(png_struct *png_ptr, png_info *info_ptr)
png_read_reset(png_ptr);
png_ptr->mode &= ~PNG_HAVE_fcTL;

png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);

if (!(png_ptr->mode & PNG_HAVE_fcTL))
png_error(png_ptr, "Missing required fcTL chunk in APNG stream");
png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);

/* We only get here for an fcTL chunk, so if PNG_HAVE_fcTL was not
* set above the chunk was present but rejected (e.g. an oversized
* or misplaced frame description); say that rather than claiming
* that the chunk is missing.
*/
if (!(png_ptr->mode & PNG_HAVE_fcTL))
png_error(png_ptr,
"Invalid or misplaced fcTL chunk in APNG stream");

png_read_reinit(png_ptr, info_ptr);
png_progressive_read_reset(png_ptr);
Expand Down
87 changes: 57 additions & 30 deletions pngrutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -3232,7 +3232,14 @@ 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
/* The minimum and maximum fcTL lengths are equal because an fcTL is
* exactly 26 bytes long: a 4-byte big-endian sequence number followed by
* 22 bytes of frame data. The earlier value of 25U for max_length was
* inconsistent with min_length=26U and would have rejected every valid
* fcTL if this table entry were ever consulted (the handler is currently
* compiled out; see the '#define png_handle_fcTL NULL' above).
*/
# 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 Expand Up @@ -4590,37 +4597,17 @@ png_read_finish_row(png_struct *png_ptr)
}
#endif /* SEQUENTIAL_READ */

void /* PRIVATE */
png_read_start_row(png_struct *png_ptr)
/* Compute the maximum pixel depth that any row could have after all of
* the enabled read transformations. This was previously open-coded
* here only; keeping it in one place makes it possible to reason about
* (and assert on) consistency with png_do_read_transformations and
* png_read_transform_info, which must agree with this value - see the
* warning in png_read_start_row.
*/
static unsigned int
png_read_max_pixel_depth(png_struct *png_ptr)
{
unsigned int max_pixel_depth;
size_t row_bytes;

png_debug(1, "in png_read_start_row");

#ifdef PNG_READ_TRANSFORMS_SUPPORTED
png_init_read_transformations(png_ptr);
#endif
if (png_ptr->interlaced != 0)
{
if ((png_ptr->transformations & PNG_INTERLACE) == 0)
png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
png_pass_ystart[0]) / png_pass_yinc[0];

else
png_ptr->num_rows = png_ptr->height;

png_ptr->iwidth = (png_ptr->width +
png_pass_inc[png_ptr->pass] - 1 -
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
}

else
{
png_ptr->num_rows = png_ptr->height;
png_ptr->iwidth = png_ptr->width;
}

max_pixel_depth = (unsigned int)png_ptr->pixel_depth;

Expand Down Expand Up @@ -4765,6 +4752,46 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
}
#endif

return max_pixel_depth;
}

void /* PRIVATE */
png_read_start_row(png_struct *png_ptr)
{
unsigned int max_pixel_depth;
size_t row_bytes;

png_debug(1, "in png_read_start_row");

#ifdef PNG_READ_TRANSFORMS_SUPPORTED
png_init_read_transformations(png_ptr);
#endif
if (png_ptr->interlaced != 0)
{
if ((png_ptr->transformations & PNG_INTERLACE) == 0)
png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
png_pass_ystart[0]) / png_pass_yinc[0];

else
png_ptr->num_rows = png_ptr->height;

png_ptr->iwidth = (png_ptr->width +
png_pass_inc[png_ptr->pass] - 1 -
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
}

else
{
png_ptr->num_rows = png_ptr->height;
png_ptr->iwidth = png_ptr->width;
}

/* Calculate the maximum transformed pixel depth (see the warning
* above png_read_max_pixel_depth).
*/
max_pixel_depth = png_read_max_pixel_depth(png_ptr);

/* This value is stored in png_struct and double checked in the row read
* code.
*/
Expand Down