Skip to content

Commit 1e40725

Browse files
committed
Merge branch 'PHP-7.2' into PHP-7.3
* PHP-7.2: Fix #77272: imagescale() may return image resource on failure
2 parents 00e5d0e + 772b1cb commit 1e40725

File tree

3 files changed

+39
-26
lines changed

3 files changed

+39
-26
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ PHP NEWS
1919
application/octet-stream). (Anatol)
2020

2121
- GD:
22+
. Fixed bug #77272 (imagescale() may return image resource on failure). (cmb)
2223
. Fixed bug #77391 (1bpp BMPs may fail to be loaded). (Romain Déoux, cmb)
2324

2425
- Mbstring:

ext/gd/libgd/gd_interpolation.c

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ static inline void _gdScaleRow(gdImagePtr pSrc, unsigned int src_width, gdImage
10201020
}
10211021
}
10221022

1023-
static inline void _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigned int src_height, gdImagePtr pDst, unsigned int dst_width, unsigned int dst_height)
1023+
static inline int _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigned int src_height, gdImagePtr pDst, unsigned int dst_width, unsigned int dst_height)
10241024
{
10251025
unsigned int u;
10261026
LineContribType * contrib;
@@ -1035,13 +1035,14 @@ static inline void _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsign
10351035

10361036
contrib = _gdContributionsCalc(dst_width, src_width, (double)dst_width / (double)src_width, pSrc->interpolation);
10371037
if (contrib == NULL) {
1038-
return;
1038+
return 0;
10391039
}
10401040
/* Scale each row */
10411041
for (u = 0; u < dst_height - 1; u++) {
10421042
_gdScaleRow(pSrc, src_width, pDst, dst_width, u, contrib);
10431043
}
10441044
_gdContributionsFree (contrib);
1045+
return 1;
10451046
}
10461047

10471048
static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImagePtr pRes, unsigned int dst_width, unsigned int dst_height, unsigned int uCol, LineContribType *contrib)
@@ -1066,7 +1067,7 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
10661067
}
10671068
}
10681069

1069-
static inline void _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_width, const unsigned int src_height, const gdImagePtr pDst, const unsigned int dst_width, const unsigned int dst_height)
1070+
static inline int _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_width, const unsigned int src_height, const gdImagePtr pDst, const unsigned int dst_width, const unsigned int dst_height)
10701071
{
10711072
unsigned int u;
10721073
LineContribType * contrib;
@@ -1081,19 +1082,21 @@ static inline void _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_w
10811082

10821083
contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation);
10831084
if (contrib == NULL) {
1084-
return;
1085+
return 0;
10851086
}
10861087
/* scale each column */
10871088
for (u = 0; u < dst_width - 1; u++) {
10881089
_gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib);
10891090
}
10901091
_gdContributionsFree(contrib);
1092+
return 1;
10911093
}
10921094

10931095
gdImagePtr gdImageScaleTwoPass(const gdImagePtr src, const unsigned int src_width, const unsigned int src_height, const unsigned int new_width, const unsigned int new_height)
10941096
{
10951097
gdImagePtr tmp_im;
10961098
gdImagePtr dst;
1099+
int scale_pass_res;
10971100

10981101
if (new_width == 0 || new_height == 0) {
10991102
return NULL;
@@ -1109,38 +1112,26 @@ gdImagePtr gdImageScaleTwoPass(const gdImagePtr src, const unsigned int src_widt
11091112
return NULL;
11101113
}
11111114
gdImageSetInterpolationMethod(tmp_im, src->interpolation_id);
1112-
_gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
1115+
scale_pass_res = _gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
1116+
if (scale_pass_res != 1) {
1117+
gdImageDestroy(tmp_im);
1118+
return NULL;
1119+
}
11131120

11141121
dst = gdImageCreateTrueColor(new_width, new_height);
11151122
if (dst == NULL) {
11161123
gdImageDestroy(tmp_im);
11171124
return NULL;
11181125
}
11191126
gdImageSetInterpolationMethod(dst, src->interpolation_id);
1120-
_gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
1121-
gdImageDestroy(tmp_im);
1122-
1123-
return dst;
1124-
}
1125-
1126-
gdImagePtr Scale(const gdImagePtr src, const unsigned int src_width, const unsigned int src_height, const gdImagePtr dst, const unsigned int new_width, const unsigned int new_height)
1127-
{
1128-
gdImagePtr tmp_im;
1129-
1130-
if (new_width == 0 || new_height == 0) {
1131-
return NULL;
1132-
}
1133-
1134-
tmp_im = gdImageCreateTrueColor(new_width, src_height);
1135-
if (tmp_im == NULL) {
1127+
scale_pass_res = _gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
1128+
if (scale_pass_res != 1) {
1129+
gdImageDestroy(dst);
1130+
gdImageDestroy(tmp_im);
11361131
return NULL;
11371132
}
1138-
gdImageSetInterpolationMethod(tmp_im, src->interpolation_id);
1139-
1140-
_gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
1141-
_gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
1142-
11431133
gdImageDestroy(tmp_im);
1134+
11441135
return dst;
11451136
}
11461137

ext/gd/tests/bug77272.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Bug #77272 (imagescale() may return image resource on failure)
3+
--INI--
4+
memory_limit=-1
5+
--SKIPIF--
6+
<?php
7+
if (!extension_loaded('gd')) die('skip gd extension not available');
8+
if (!GD_BUNGLED && version_compare(GD_VERSION, '2.2.5', '<=')) die('skip upstream fix not yet released');
9+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
10+
?>
11+
--FILE--
12+
<?php
13+
$img = imagecreate(2**28, 1);
14+
var_dump(imagescale($img, 1, 1, IMG_TRIANGLE));
15+
?>
16+
===DONE===
17+
--EXPECTF--
18+
Warning: imagescale():%S product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully
19+
in %s on line %d
20+
bool(false)
21+
===DONE===

0 commit comments

Comments
 (0)