summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2016-07-18 00:17:48 -0700
committerStanislav Malyshev <stas@php.net>2016-07-18 00:17:48 -0700
commitd1a491acf31cf6d2ba65cc7c46fe963a510cd91f (patch)
treefcde86948297cc900c3c1d3f0db07d5027658e20
parenteebcbd5de38a0f1c2876035402cb770e37476519 (diff)
downloadphp-git-d1a491acf31cf6d2ba65cc7c46fe963a510cd91f.tar.gz
Fix for bug #72558, Integer overflow error within _gdContributionsAlloc()
-rw-r--r--ext/gd/libgd/gd.c2
-rw-r--r--ext/gd/libgd/gd_interpolation.c116
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)