CVE-2016-5735: Integer Overflow or Wraparound (CWE-190)
value: Integer overflow in the rwpng_read_image24_libpng function in rwpng.c in pngquant 2.7.0 allows remote attackers to have unspecified impact via a crafted PNG file, which triggers a buffer overflow.
CWE description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
CVSS v3 base score: 7.8
Published: 2017-05-23T04:29Z
Repository: https://github.com/pornel/pngquant
Language: C
Files changed: rwpng.c
Commit date: 2016-06-23 16:10:57 +0100
Commit message: Fix integer overflow in rwpng.h (CVE-2016-5735)

Reported by Choi Jaeseung 
Found with Sparrow (http://ropas.snu.ac.kr/sparrow)
Diff: diff --git a/rwpng.c b/rwpng.c
index aeb4696..e3f59d1 100644
--- a/rwpng.c
+++ b/rwpng.c
@@ -242,16 +242,10 @@ static pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainp
      * compression_type and filter_type => NULLs] */
 
     png_get_IHDR(png_ptr, info_ptr, &mainprog_ptr->width, &mainprog_ptr->height,
                  &bit_depth, &color_type, NULL, NULL, NULL);
 
-    // For overflow safety reject images that won't fit in 32-bit
-    if (mainprog_ptr->width > INT_MAX/mainprog_ptr->height) {
-        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-        return PNG_OUT_OF_MEMORY_ERROR;  /* not quite true, but whatever */
-    }
-
     /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
      * transparency chunks to full alpha channel; strip 16-bit-per-sample
      * images to 8 bits per sample; and convert grayscale to RGB[A] */
 
     /* GRR TO DO:  preserve all safe-to-copy ancillary PNG chunks */
@@ -302,10 +296,16 @@ static pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainp
 
     png_read_update_info(png_ptr, info_ptr);
 
     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
+    // For overflow safety reject images that won't fit in 32-bit
+    if (rowbytes > INT_MAX/mainprog_ptr->height) {
+        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+        return PNG_OUT_OF_MEMORY_ERROR;
+    }
+
     if ((mainprog_ptr->rgba_data = malloc(rowbytes * mainprog_ptr->height)) == NULL) {
         fprintf(stderr, "pngquant readpng:  unable to allocate image data\n");
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
         return PNG_OUT_OF_MEMORY_ERROR;
     }

Vulnerable code:     // For overflow safety reject images that won't fit in 32-bit
    if (mainprog_ptr->width > INT_MAX/mainprog_ptr->height) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return PNG_OUT_OF_MEMORY_ERROR;  /* not quite true, but whatever */
    }

Fixed code:     // For overflow safety reject images that won't fit in 32-bit
    if (rowbytes > INT_MAX/mainprog_ptr->height) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return PNG_OUT_OF_MEMORY_ERROR;
    }