From c026b075296e0d06fda5b20ad625450039a03b05 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Sun, 21 Dec 2014 18:42:37 -0600 Subject: [PATCH] [libpng17] Restored a test on width that was removed from png.c at libpng-1.6.9 (Bug report by Alex Eubanks). Fixed an overflow in png_combine_row with very wide interlaced images. --- ANNOUNCE | 7 +++++-- CHANGES | 5 ++++- png.c | 38 +++++++++++++++++++++++++++++++++++--- pngrutil.c | 8 ++++---- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index de8ddeae0..25469f3b4 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.7.0beta44 - December 18, 2014 +Libpng 1.7.0beta44 - December 22, 2014 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -665,7 +665,10 @@ Version 1.7.0beta43 [December 18, 2014] renamed scripts/*.dfn to scripts/*.c (Bob Friesenhahn and John Bowler). Quiet a "comparison always true" warning in pngstest.c (John Bowler). -Version 1.7.0beta44 [December 18, 2014] +Version 1.7.0beta44 [December 22, 2014] + Restored a test on width that was removed from png.c at libpng-1.6.9 + (Bug report by Alex Eubanks). + Fixed an overflow in png_combine_row with very wide interlaced images. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index a384ee35b..64471b2d8 100644 --- a/CHANGES +++ b/CHANGES @@ -4954,7 +4954,10 @@ Version 1.7.0beta43 [December 18, 2014] renamed scripts/*.dfn to scripts/*.c (Bob Friesenhahn and John Bowler). Quiet a "comparison always true" warning in pngstest.c (John Bowler). -Version 1.7.0beta44 [December 18, 2014] +Version 1.7.0beta44 [December 22, 2014] + Restored a test on width that was removed from png.c at libpng-1.6.9 + (Bug report by Alex Eubanks). + Fixed an overflow in png_combine_row with very wide interlaced images. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/png.c b/png.c index d58bbb9ab..32a9c01a3 100644 --- a/png.c +++ b/png.c @@ -691,13 +691,13 @@ png_get_copyright(png_const_structrp png_ptr) #else # ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.7.0beta44 - December 18, 2014" PNG_STRING_NEWLINE \ + "libpng version 1.7.0beta44 - December 22, 2014" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE; # else - return "libpng version 1.7.0beta44 - December 18, 2014\ + return "libpng version 1.7.0beta44 - December 22, 2014\ Copyright (c) 1998-2014 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; @@ -1231,7 +1231,7 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) * (1/white-y), so we can immediately see that as white-y approaches 0 the * accuracy inherent in the cHRM chunk drops off substantially. * - * libpng arithmetic: a simple invertion of the above equations + * libpng arithmetic: a simple inversion of the above equations * ------------------------------------------------------------ * * white_scale = 1/white-y @@ -2357,6 +2357,17 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr) #endif /* COLORSPACE */ +#ifdef __GNUC__ +/* This exists solely to work round a warning from GNU C. */ +static int /* PRIVATE */ +png_gt(size_t a, size_t b) +{ + return a > b; +} +#else +# define png_gt(a,b) ((a) > (b)) +#endif + void /* PRIVATE */ png_check_IHDR(png_const_structrp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, @@ -2376,6 +2387,27 @@ png_check_IHDR(png_const_structrp png_ptr, png_warning(png_ptr, "Invalid image width in IHDR"); error = 1; } + else if (png_gt(width, + (PNG_SIZE_MAX >> 3) /* 8-byte RGBA pixels */ + - 48 /* big_row_buf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding width to multiple of 8 pix */ + - 8)) /* extra max_pixel_depth pad */ + { + /* The size of the row must be within the limits of this architecture. + * Because the read code can perform arbitrary transformations the + * maximum size is checked here. Because the code in png_read_start_row + * adds extra space "for safety's sake" in several places a conservative + * limit is used here. + * + * NOTE: it would be far better to check the size that is actually used, + * but the effect in the real world is minor and the changes are more + * extensive, therefore much more dangerous and much more difficult to + * write in a way that avoids compiler warnings. + */ + png_warning(png_ptr, "Image width is too large for this architecture"); + error = 1; + } else { # ifdef PNG_SET_USER_LIMITS_SUPPORTED diff --git a/pngrutil.c b/pngrutil.c index 72e3cd1a3..3a2ca6da2 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -2974,7 +2974,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) { unsigned int pixel_depth = png_ptr->transformed_pixel_depth; png_const_bytep sp = png_ptr->row_buf + 1; - png_uint_32 row_width = png_ptr->width; + png_alloc_size_t row_width = png_ptr->width; unsigned int pass = png_ptr->pass; png_bytep end_ptr = 0; png_byte end_byte = 0; @@ -3247,7 +3247,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) /* But don't allow this number to exceed the actual row width. */ if (bytes_to_copy > row_width) - bytes_to_copy = row_width; + bytes_to_copy = (unsigned int)/*SAFE*/row_width; } else /* normal row; Adam7 only ever gives us one pixel to copy. */ @@ -3427,7 +3427,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) dp += bytes_to_jump; row_width -= bytes_to_jump; if (bytes_to_copy > row_width) - bytes_to_copy = row_width; + bytes_to_copy = (unsigned int)/*SAFE*/row_width; } } @@ -4205,7 +4205,7 @@ png_read_start_row(png_structrp png_ptr) max_pixel_depth = png_ptr->pixel_depth; - /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of + /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of * calculations to calculate the final pixel depth, then * png_do_read_transforms actually does the transforms. This means that the * code which effectively calculates this value is actually repeated in three