diff options
author | Stanislav Malyshev <stas@php.net> | 2016-07-18 00:17:48 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2016-07-18 00:17:48 -0700 |
commit | d1a491acf31cf6d2ba65cc7c46fe963a510cd91f (patch) | |
tree | fcde86948297cc900c3c1d3f0db07d5027658e20 | |
parent | eebcbd5de38a0f1c2876035402cb770e37476519 (diff) | |
download | php-git-d1a491acf31cf6d2ba65cc7c46fe963a510cd91f.tar.gz |
Fix for bug #72558, Integer overflow error within _gdContributionsAlloc()
-rw-r--r-- | ext/gd/libgd/gd.c | 2 | ||||
-rw-r--r-- | ext/gd/libgd/gd_interpolation.c | 116 |
2 files changed, 70 insertions, 48 deletions
diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 3a9577859e..c501c67673 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -190,7 +190,7 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy) return NULL; } - if (overflow2(sizeof(int), sx)) { + if (overflow2(sizeof(int *), sx)) { return NULL; } diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index 4fa23f0a14..0ff10b9f4f 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -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) |