[libpng16] Document need to check for integer overflow when allocating a pixel

buffer for multiple rows in contrib/gregbook, contrib/pngminus, example.c, and
in the manual (suggested by Jaeseung Choi).
This commit is contained in:
Glenn Randers-Pehrson
2017-04-22 15:21:58 -05:00
parent 13370c536c
commit 53f22aed41
13 changed files with 118 additions and 18 deletions

View File

@@ -264,6 +264,12 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
*pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
*pChannels = (int)png_get_channels(png_ptr, info_ptr);
/* Guard against integer overflow */
if (height > ((size_t)(-1))/rowbytes) {
fprintf(stderr, "readpng: image_data buffer would be too large\n",
return NULL;
}
if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;

View File

@@ -154,12 +154,17 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
*pRowbytes = rowbytes = channels*width;
*pChannels = channels;
if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height));
/* Guard against integer overflow */
if (height > ((size_t)(-1))/rowbytes) {
fprintf(stderr, PROGNAME ": image_data buffer would be too large\n",
return NULL;
}
Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height));
if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
return NULL;
}
/* now we can go ahead and just read the whole image */

View File

@@ -496,6 +496,12 @@ static int rpng_win_create_window(HINSTANCE hInst, int showmode)
wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2;
/* Guard against integer overflow */
if (image_height > ((size_t)(-1))/wimage_rowbytes) {
fprintf(stderr, PROGNAME ": image_data buffer would be too large\n",
return 4; /* fail */
}
if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
wimage_rowbytes*image_height)))
{

View File

@@ -650,6 +650,13 @@ static void rpng2_win_init()
Trace((stderr, " width = %ld\n", rpng2_info.width))
Trace((stderr, " height = %ld\n", rpng2_info.height))
/* Guard against integer overflow */
if (rpng2_info.height > ((size_t)(-1))/rowbytes) {
fprintf(stderr, PROGNAME ": image_data buffer would be too large\n",
readpng2_cleanup(&rpng2_info);
return;
}
rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
if (!rpng2_info.image_data) {
readpng2_cleanup(&rpng2_info);

View File

@@ -780,6 +780,13 @@ static void rpng2_x_init(void)
Trace((stderr, " width = %ld\n", rpng2_info.width))
Trace((stderr, " height = %ld\n", rpng2_info.height))
/* Guard against integer overflow */
if (rpng2_info.height > ((size_t)(-1))/rpng2_info.rowbytes) {
fprintf(stderr, PROGNAME ": image_data buffer would be too large\n");
readpng2_cleanup(&rpng2_info);
return;
}
rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
if (!rpng2_info.image_data) {
readpng2_cleanup(&rpng2_info);

View File

@@ -702,7 +702,17 @@ int main(int argc, char **argv)
if (wpng_info.interlaced) {
long i;
ulg bytes;
ulg image_bytes = rowbytes * wpng_info.height; /* overflow? */
ulg image_bytes;
/* Guard against integer overflow */
if (wpng_info_height > ((size_t)(-1)/rowbytes) {
fprintf(stderr, PROGNAME ": image_data buffer too large\n");
writepng_cleanup(&wpng_info);
wpng_cleanup();
exit(5);
}
image_bytes = rowbytes * wpng_info.height; /* overflow? */
wpng_info.image_data = (uch *)malloc(image_bytes);
wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));