[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).
diff --git a/ANNOUNCE b/ANNOUNCE
index 9895496..3c86884 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,4 +1,4 @@
-Libpng 1.6.30beta02 - April 1, 2017
+Libpng 1.6.30beta02 - April 21, 2017
 
 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.
@@ -32,7 +32,10 @@
   Silence clang -Wcomma and const drop warnings (Viktor Szakats).
   Update Sourceforge URLs in documentation (https instead of http).
 
-Version 1.6.30beta02 [April 1, 2017]
+Version 1.6.30beta02 [April 21, 2017]
+  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).
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index 13cfeea..9bd8785 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5827,7 +5827,10 @@
   Silence clang -Wcomma and const drop warnings (Viktor Szakats).
   Update Sourceforge URLs in documentation (https instead of http).
 
-Version 1.6.30beta02 [April 16, 2017]
+Version 1.6.30beta02 [April 21, 2017]
+  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).
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/contrib/gregbook/readpng.c b/contrib/gregbook/readpng.c
index 9167403..e6a01c6 100644
--- a/contrib/gregbook/readpng.c
+++ b/contrib/gregbook/readpng.c
@@ -264,6 +264,12 @@
     *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;
diff --git a/contrib/gregbook/readppm.c b/contrib/gregbook/readppm.c
index 7fefc39..3a41f3e 100644
--- a/contrib/gregbook/readppm.c
+++ b/contrib/gregbook/readppm.c
@@ -154,12 +154,17 @@
     *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 */
 
diff --git a/contrib/gregbook/rpng-win.c b/contrib/gregbook/rpng-win.c
index cd55439..313beaf 100644
--- a/contrib/gregbook/rpng-win.c
+++ b/contrib/gregbook/rpng-win.c
@@ -496,6 +496,12 @@
 
     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)))
     {
diff --git a/contrib/gregbook/rpng2-win.c b/contrib/gregbook/rpng2-win.c
index c924c1c..8720bb0 100644
--- a/contrib/gregbook/rpng2-win.c
+++ b/contrib/gregbook/rpng2-win.c
@@ -650,6 +650,13 @@
     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);
diff --git a/contrib/gregbook/rpng2-x.c b/contrib/gregbook/rpng2-x.c
index 0c8ddeb..2585203 100644
--- a/contrib/gregbook/rpng2-x.c
+++ b/contrib/gregbook/rpng2-x.c
@@ -780,6 +780,13 @@
     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);
diff --git a/contrib/gregbook/wpng.c b/contrib/gregbook/wpng.c
index a06e352..3b5b811 100644
--- a/contrib/gregbook/wpng.c
+++ b/contrib/gregbook/wpng.c
@@ -702,7 +702,17 @@
     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 *));
diff --git a/contrib/pngminus/png2pnm.c b/contrib/pngminus/png2pnm.c
index 995fddf..4f01a5e 100644
--- a/contrib/pngminus/png2pnm.c
+++ b/contrib/pngminus/png2pnm.c
@@ -320,6 +320,10 @@
   /* row_bytes is the width x number of channels x (bit-depth / 8) */
   row_bytes = png_get_rowbytes (png_ptr, info_ptr);
 
+  if (height > ((size_t)(-1))/row_bytes) /* too big */ {
+    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+    return FALSE;
+  }
   if ((png_pixels = (png_byte *)
      malloc (row_bytes * height * sizeof (png_byte))) == NULL) {
     png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
diff --git a/contrib/pngminus/pnm2png.c b/contrib/pngminus/pnm2png.c
index 5de828a..7346d57 100644
--- a/contrib/pngminus/pnm2png.c
+++ b/contrib/pngminus/pnm2png.c
@@ -373,6 +373,9 @@
     /* row_bytes is the width x number of channels x (bit-depth / 8) */
     row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
 
+  if (height > ((size_t)(-1))/row_bytes) /* too big */ {
+    return FALSE;
+  }
   if ((png_pixels = (png_byte *)
      malloc (row_bytes * height * sizeof (png_byte))) == NULL)
     return FALSE;
diff --git a/libpng-manual.txt b/libpng-manual.txt
index a339216..c3ee45b 100644
--- a/libpng-manual.txt
+++ b/libpng-manual.txt
@@ -1,6 +1,6 @@
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.30beta02 - April 3, 2017
+ libpng version 1.6.30beta02 - April 19, 2017
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
  Copyright (c) 1998-2016 Glenn Randers-Pehrson
@@ -11,7 +11,7 @@
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.30beta02 - April 3, 2017
+ libpng versions 0.97, January 1998, through 1.6.30beta02 - April 19, 2017
  Updated and distributed by Glenn Randers-Pehrson
  Copyright (c) 1998-2016 Glenn Randers-Pehrson
 
@@ -1190,7 +1190,20 @@
    png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 Alternatively you could allocate your image in one big block and define
-row_pointers[i] to point into the proper places in your block.
+row_pointers[i] to point into the proper places in your block, but first
+be sure that your platform is able to allocate such a large buffer:
+
+   /* Guard against integer overflow */
+   if (height > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
+   png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size);
+
+   for (int i=0; i<height, i++)
+      row_pointers[i]=buffer+i*width*pixel_size;
+
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 If you use png_set_rows(), the application is responsible for freeing
 row_pointers (and row_pointers[i], if they were separately allocated).
@@ -2146,6 +2159,16 @@
 array of pointers to each row, as it will be needed for some
 of the functions below.
 
+Be sure that your platform can allocate the buffer that you'll need.
+libpng internally checks for oversize width, but you'll need to
+do your own check for number_of_rows*width*pixel_size if you are using
+a multiple-row buffer:
+
+   /* Guard against integer overflow */
+   if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
 Remember: Before you call png_read_update_info(), the png_get_*()
 functions return the values corresponding to the original PNG image.
 After you call png_read_update_info the values refer to the image
diff --git a/libpng.3 b/libpng.3
index 3079c7d..2466e34 100644
--- a/libpng.3
+++ b/libpng.3
@@ -1,4 +1,4 @@
-.TH LIBPNG 3 "April 3, 2017"
+.TH LIBPNG 3 "April 19, 2017"
 .SH NAME
 libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02
 .SH SYNOPSIS
@@ -510,7 +510,7 @@
 .SH LIBPNG.TXT
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.30beta02 - April 3, 2017
+ libpng version 1.6.30beta02 - April 19, 2017
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
  Copyright (c) 1998-2016 Glenn Randers-Pehrson
@@ -521,7 +521,7 @@
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.30beta02 - April 3, 2017
+ libpng versions 0.97, January 1998, through 1.6.30beta02 - April 19, 2017
  Updated and distributed by Glenn Randers-Pehrson
  Copyright (c) 1998-2016 Glenn Randers-Pehrson
 
@@ -1700,7 +1700,20 @@
    png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 Alternatively you could allocate your image in one big block and define
-row_pointers[i] to point into the proper places in your block.
+row_pointers[i] to point into the proper places in your block, but first
+be sure that your platform is able to allocate such a large buffer:
+
+   /* Guard against integer overflow */
+   if (height > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
+   png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size);
+
+   for (int i=0; i<height, i++)
+      row_pointers[i]=buffer+i*width*pixel_size;
+
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 If you use png_set_rows(), the application is responsible for freeing
 row_pointers (and row_pointers[i], if they were separately allocated).
@@ -2656,6 +2669,16 @@
 array of pointers to each row, as it will be needed for some
 of the functions below.
 
+Be sure that your platform can allocate the buffer that you'll need.
+libpng internally checks for oversize width, but you'll need to
+do your own check for number_of_rows*width*pixel_size if you are using
+a multiple-row buffer:
+
+   /* Guard against integer overflow */
+   if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
 Remember: Before you call png_read_update_info(), the png_get_*()
 functions return the values corresponding to the original PNG image.
 After you call png_read_update_info the values refer to the image
@@ -6026,7 +6049,7 @@
 
 Thanks to Frank J. T. Wojcik for helping with the documentation.
 
-Libpng version 1.6.30beta02 - April 3, 2017:
+Libpng version 1.6.30beta02 - April 19, 2017:
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
 Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
 
@@ -6051,7 +6074,7 @@
 
 This code is released under the libpng license.
 
-libpng versions 1.0.7, July 1, 2000 through 1.6.30beta02, April 3, 2017 are
+libpng versions 1.0.7, July 1, 2000 through 1.6.30beta02, April 19, 2017 are
 Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
 derived from libpng-1.0.6, and are distributed according to the same
 disclaimer and license as libpng-1.0.6 with the following individuals
@@ -6179,7 +6202,7 @@
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-April 3, 2017
+April 19, 2017
 
 .\" end of man page
 
diff --git a/libpngpf.3 b/libpngpf.3
index 0844b73..93b781c 100644
--- a/libpngpf.3
+++ b/libpngpf.3
@@ -1,4 +1,4 @@
-.TH LIBPNGPF 3 "April 1, 2017"
+.TH LIBPNGPF 3 "April 19, 2017"
 .SH NAME
 libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02
 (private functions)