[libpng17] Added byte, short and other overflow checking

Added 'assert' based overflow checking for debug builds for char
and short assignments. Simply ignore the error in release builds
(a truncated value will be used without warning). Controlled by
PNG_RANGE_CHECK_SUPPORTED.
This commit is contained in:
John Bowler
2015-03-22 15:57:53 -05:00
committed by Glenn Randers-Pehrson
parent 382de60042
commit 82fa6aed0e
14 changed files with 618 additions and 508 deletions

View File

@@ -24,10 +24,10 @@
void PNGAPI
png_save_uint_32(png_bytep buf, png_uint_32 i)
{
buf[0] = (png_byte)((i >> 24) & 0xff);
buf[1] = (png_byte)((i >> 16) & 0xff);
buf[2] = (png_byte)((i >> 8) & 0xff);
buf[3] = (png_byte)(i & 0xff);
buf[0] = PNG_BYTE(i >> 24);
buf[1] = PNG_BYTE(i >> 16);
buf[2] = PNG_BYTE(i >> 8);
buf[3] = PNG_BYTE(i);
}
/* Place a 16-bit number into a buffer in PNG byte order.
@@ -37,8 +37,8 @@ png_save_uint_32(png_bytep buf, png_uint_32 i)
void PNGAPI
png_save_uint_16(png_bytep buf, unsigned int i)
{
buf[0] = (png_byte)((i >> 8) & 0xff);
buf[1] = (png_byte)(i & 0xff);
buf[0] = PNG_BYTE(i >> 8);
buf[1] = PNG_BYTE(i);
}
#endif
@@ -279,10 +279,10 @@ optimize_cmf(png_bytep data, png_alloc_size_t data_size)
z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
data[0] = (png_byte)(z_cmf & 0xff);
data[0] = png_check_byte(0/*TODO: fixme*/, z_cmf);
tmp = data[1] & 0xe0;
tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
data[1] = (png_byte)(tmp & 0xff);
data[1] = png_check_byte(0/*TODO: fixme*/, tmp);
}
}
}
@@ -874,17 +874,18 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
#endif
/* Save the relevant information */
png_ptr->bit_depth = (png_byte)(bit_depth & 0xff);
png_ptr->color_type = (png_byte)(color_type & 0xff);
png_ptr->interlaced = (png_byte)(interlace_type & 0xff);
png_ptr->bit_depth = png_check_byte(png_ptr, bit_depth);
png_ptr->color_type = png_check_byte(png_ptr, color_type);
png_ptr->interlaced = png_check_byte(png_ptr, interlace_type);
#ifdef PNG_MNG_FEATURES_SUPPORTED
png_ptr->filter_type = (png_byte)(filter_type & 0xff);
png_ptr->filter_type = png_check_byte(png_ptr, filter_type);
#endif
png_ptr->compression_type = (png_byte)(compression_type & 0xff);
png_ptr->compression_type = png_check_byte(png_ptr, compression_type);
png_ptr->width = width;
png_ptr->height = height;
png_ptr->pixel_depth = (png_byte)((bit_depth * png_ptr->channels) & 0xff);
png_ptr->pixel_depth = png_check_byte(png_ptr,
bit_depth * png_ptr->channels);
png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
/* Set the usr info, so any transformations can modify it */
png_ptr->usr_width = png_ptr->width;
@@ -894,11 +895,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
/* Pack the header information into the buffer */
png_save_uint_32(buf, width);
png_save_uint_32(buf + 4, height);
buf[8] = (png_byte)(bit_depth & 0xff);
buf[9] = (png_byte)(color_type & 0xff);
buf[10] = (png_byte)(compression_type & 0xff);
buf[11] = (png_byte)(filter_type & 0xff);
buf[12] = (png_byte)(interlace_type & 0xff);
buf[8] = png_check_byte(png_ptr, bit_depth);
buf[9] = png_check_byte(png_ptr, color_type);
buf[10] = png_check_byte(png_ptr, compression_type);
buf[11] = png_check_byte(png_ptr, filter_type);
buf[12] = png_check_byte(png_ptr, interlace_type);
/* Write the chunk */
png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
@@ -1183,7 +1184,7 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent)
png_warning(png_ptr,
"Invalid sRGB rendering intent specified");
buf[0]=(png_byte)(srgb_intent & 0xff);
buf[0] = png_check_byte(png_ptr, srgb_intent);
png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
}
#endif
@@ -1273,10 +1274,9 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
png_write_chunk_header(png_ptr, png_sPLT,
(png_uint_32)(name_len + 2 + palette_size));
png_write_chunk_data(png_ptr, (png_bytep)new_name,
(png_size_t)(name_len + 1));
png_write_chunk_data(png_ptr, new_name, name_len + 1);
png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
png_write_chunk_data(png_ptr, &spalette->depth, 1);
/* Loop through each palette entry, writing appropriately */
#ifdef PNG_POINTER_INDEXING_SUPPORTED
@@ -1284,10 +1284,10 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
{
if (spalette->depth == 8)
{
entrybuf[0] = (png_byte)(ep->red & 0xff);
entrybuf[1] = (png_byte)(ep->green & 0xff);
entrybuf[2] = (png_byte)(ep->blue & 0xff);
entrybuf[3] = (png_byte)(ep->alpha & 0xff);
entrybuf[0] = png_check_byte(png_ptr, ep->red);
entrybuf[1] = png_check_byte(png_ptr, ep->green);
entrybuf[2] = png_check_byte(png_ptr, ep->blue);
entrybuf[3] = png_check_byte(png_ptr, ep->alpha);
png_save_uint_16(entrybuf + 4, ep->frequency);
}
@@ -1308,10 +1308,10 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
{
if (spalette->depth == 8)
{
entrybuf[0] = (png_byte)(ep[i].red & 0xff);
entrybuf[1] = (png_byte)(ep[i].green & 0xff);
entrybuf[2] = (png_byte)(ep[i].blue & 0xff);
entrybuf[3] = (png_byte)(ep[i].alpha & 0xff);
entrybuf[0] = png_check_byte(png_ptr, ep[i].red);
entrybuf[1] = png_check_byte(png_ptr, ep[i].green);
entrybuf[2] = png_check_byte(png_ptr, ep[i].blue);
entrybuf[3] = png_check_byte(png_ptr, ep[i].alpha);
png_save_uint_16(entrybuf + 4, ep[i].frequency);
}
@@ -1347,8 +1347,8 @@ png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
{
png_byte maxbits;
maxbits = (png_byte)((color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
png_ptr->usr_bit_depth) & 0xff);
maxbits = png_check_byte(png_ptr, color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
png_ptr->usr_bit_depth);
if (sbit->red == 0 || sbit->red > maxbits ||
sbit->green == 0 || sbit->green > maxbits ||
@@ -1789,7 +1789,7 @@ png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
png_save_int_32(buf, x_offset);
png_save_int_32(buf + 4, y_offset);
buf[8] = (png_byte)(unit_type & 0xff);
buf[8] = png_check_byte(png_ptr, unit_type);
png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
}
@@ -1844,8 +1844,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
png_write_chunk_data(png_ptr, new_purpose, purpose_len);
png_save_int_32(buf, X0);
png_save_int_32(buf + 4, X1);
buf[8] = (png_byte)(type & 0xff);
buf[9] = (png_byte)(nparams & 0xff);
buf[8] = png_check_byte(png_ptr, type);
buf[9] = png_check_byte(png_ptr, nparams);
png_write_chunk_data(png_ptr, buf, (png_size_t)10);
png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
@@ -1880,7 +1880,7 @@ png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
return;
}
buf[0] = (png_byte)(unit & 0xff);
buf[0] = png_check_byte(png_ptr, unit);
memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */
memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
@@ -1905,7 +1905,7 @@ png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
png_save_uint_32(buf, x_pixels_per_unit);
png_save_uint_32(buf + 4, y_pixels_per_unit);
buf[8] = (png_byte)(unit_type & 0xff);
buf[8] = png_check_byte(png_ptr, unit_type);
png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
}
@@ -2018,7 +2018,7 @@ png_write_start_row(png_structrp png_ptr)
/* 1.5.6: added to allow checking in the row write code. */
png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
png_ptr->maximum_pixel_depth = (png_byte)(usr_pixel_depth & 0xff);
png_ptr->maximum_pixel_depth = png_check_byte(png_ptr, usr_pixel_depth);
/* Set up row buffer */
png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
@@ -2046,7 +2046,8 @@ png_write_start_row(png_structrp png_ptr)
png_write_alloc_filter_row_buffers(png_ptr, filters);
png_ptr->do_filter = (png_byte)filters; /* in case it was changed above */
/* in case it was changed above */
png_ptr->do_filter = png_check_byte(png_ptr, filters);
#else
png_ptr->do_filter = PNG_FILTER_NONE;
#endif /* WRITE_FILTER */
@@ -2214,7 +2215,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
if (shift == 0)
{
shift = 7;
*dp++ = (png_byte)(d & 0xff);
*dp++ = png_check_byte(0/*TODO: fixme*/, d);
d = 0;
}
@@ -2223,7 +2224,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
}
if (shift != 7)
*dp = (png_byte)(d & 0xff);
*dp = png_check_byte(0/*TODO: fixme*/, d);
break;
}
@@ -2252,7 +2253,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
if (shift == 0)
{
shift = 6;
*dp++ = (png_byte)(d & 0xff);
*dp++ = png_check_byte(0/*TODO: fixme*/, d);
d = 0;
}
@@ -2260,7 +2261,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
shift -= 2;
}
if (shift != 6)
*dp = (png_byte)(d & 0xff);
*dp = png_check_byte(0/*TODO: fixme*/, d);
break;
}
@@ -2288,7 +2289,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
if (shift == 0)
{
shift = 4;
*dp++ = (png_byte)(d & 0xff);
*dp++ = png_check_byte(0/*TODO: fixme*/, d);
d = 0;
}
@@ -2296,7 +2297,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
shift -= 4;
}
if (shift != 4)
*dp = (png_byte)(d & 0xff);
*dp = png_check_byte(0/*TODO: fixme*/, d);
break;
}