]> granicus.if.org Git - php/commitdiff
Fix for bug #72558, Integer overflow error within _gdContributionsAlloc()
authorStanislav Malyshev <stas@php.net>
Mon, 18 Jul 2016 07:17:48 +0000 (00:17 -0700)
committerStanislav Malyshev <stas@php.net>
Mon, 18 Jul 2016 07:17:48 +0000 (00:17 -0700)
ext/gd/libgd/gd.c
ext/gd/libgd/gd_interpolation.c

index 3a9577859e962badfb6311de64343d7bc6444eb3..c501c676734b3c0ba1faccb2c513632109766629 100644 (file)
@@ -190,7 +190,7 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
                return NULL;
        }
 
-       if (overflow2(sizeof(int), sx)) {
+       if (overflow2(sizeof(int *), sx)) {
                return NULL;
        }
 
index 4fa23f0a1469a5e8cf2e43d02ec66d4b18521d3e..0ff10b9f4f08e42a8b34d74f6339a1e01a772c84 100644 (file)
@@ -881,20 +881,39 @@ int getPixelInterpolated(gdImagePtr im, const double x, const double y, const in
 static inline LineContribType * _gdContributionsAlloc(unsigned int line_length, unsigned int windows_size)
 {
        unsigned int u = 0;
-    LineContribType *res;
+       LineContribType *res;
+       int overflow_error = 0;
 
        res = (LineContribType *) gdMalloc(sizeof(LineContribType));
        if (!res) {
                return NULL;
        }
-    res->WindowSize = windows_size;
-    res->LineLength = line_length;
-    res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType));
-
-    for (u = 0 ; u < line_length ; u++) {
-        res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
-    }
-    return res;
+       res->WindowSize = windows_size;
+       res->LineLength = line_length;
+       if (overflow2(line_length, sizeof(ContributionType))) {
+               return NULL;
+       }
+       res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType));
+       if (res->ContribRow == NULL) {
+               gdFree(res);
+               return NULL;
+       }
+       for (u = 0 ; u < line_length ; u++) {
+               if (overflow2(windows_size, sizeof(double))) {
+                       overflow_error = 1;
+               } else {
+                       res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
+               }
+               if (overflow_error == 1 || res->ContribRow[u].Weights == NULL) {
+                       u--;
+                       while (u >= 0) {
+                               gdFree(res->ContribRow[u].Weights);
+                               u--;
+                       }
+                       return NULL;
+               }
+       }
+       return res;
 }
 
 static inline void _gdContributionsFree(LineContribType * p)
@@ -909,59 +928,62 @@ static inline void _gdContributionsFree(LineContribType * p)
 
 static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, double scale_d,  const interpolation_method pFilter)
 {
-    double width_d;
-    double scale_f_d = 1.0;
-    const double filter_width_d = DEFAULT_BOX_RADIUS;
+       double width_d;
+       double scale_f_d = 1.0;
+       const double filter_width_d = DEFAULT_BOX_RADIUS;
        int windows_size;
        unsigned int u;
        LineContribType *res;
+       int overflow_error = 0;
 
-    if (scale_d < 1.0) {
-        width_d = filter_width_d / scale_d;
-        scale_f_d = scale_d;
-    }  else {
-        width_d= filter_width_d;
-    }
-
-    windows_size = 2 * (int)ceil(width_d) + 1;
-    res = _gdContributionsAlloc(line_size, windows_size);
+       if (scale_d < 1.0) {
+               width_d = filter_width_d / scale_d;
+               scale_f_d = scale_d;
+       }  else {
+               width_d= filter_width_d;
+       }
 
-    for (u = 0; u < line_size; u++) {
-        const double dCenter = (double)u / scale_d;
-        /* get the significant edge points affecting the pixel */
-        register int iLeft = MAX(0, (int)floor (dCenter - width_d));
-        int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1);
-        double dTotalWeight = 0.0;
+       windows_size = 2 * (int)ceil(width_d) + 1;
+       res = _gdContributionsAlloc(line_size, windows_size);
+       if (res == NULL) {
+               return NULL;
+       }
+       for (u = 0; u < line_size; u++) {
+       const double dCenter = (double)u / scale_d;
+       /* get the significant edge points affecting the pixel */
+       register int iLeft = MAX(0, (int)floor (dCenter - width_d));
+       int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1);
+       double dTotalWeight = 0.0;
                int iSrc;
 
-        /* Cut edge points to fit in filter window in case of spill-off */
-        if (iRight - iLeft + 1 > windows_size)  {
-            if (iLeft < ((int)src_size - 1 / 2))  {
-                iLeft++;
-            } else {
-                iRight--;
-            }
-        }
+       /* Cut edge points to fit in filter window in case of spill-off */
+       if (iRight - iLeft + 1 > windows_size)  {
+               if (iLeft < ((int)src_size - 1 / 2))  {
+                       iLeft++;
+               } else {
+                       iRight--;
+               }
+       }
 
-        res->ContribRow[u].Left = iLeft;
-        res->ContribRow[u].Right = iRight;
+       res->ContribRow[u].Left = iLeft;
+       res->ContribRow[u].Right = iRight;
 
-        for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
-            dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] =  scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
-        }
+       for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
+               dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] =  scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
+       }
 
                if (dTotalWeight < 0.0) {
                        _gdContributionsFree(res);
                        return NULL;
                }
 
-        if (dTotalWeight > 0.0) {
-            for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
-                res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight;
-            }
-        }
-   }
-   return res;
+       if (dTotalWeight > 0.0) {
+               for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
+                       res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight;
+               }
+       }
+       }
+       return res;
 }
 
 static inline void _gdScaleRow(gdImagePtr pSrc,  unsigned int src_width, gdImagePtr dst, unsigned int dst_width, unsigned int row, LineContribType *contrib)