Skip to content

Commit 772b1cb

Browse files
committed
Fix #77272: imagescale() may return image resource on failure
`_gdScaleHoriz()` and `_gdScaleVert()` may fail, but don't signal failure since they are void functions. We change that according to upstream libgd. We also remove the unused `Scale()` function, which doesn't exist in upstream libgd either, right away.
1 parent 5d33024 commit 772b1cb

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
@@ -6,6 +6,7 @@ PHP NEWS
66
. Fixed bug #77339 (__callStatic may get incorrect arguments). (Dmitry)
77

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

1112
- MySQLnd:

ext/gd/libgd/gd_interpolation.c

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

1024-
static inline void _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigned int src_height, gdImagePtr pDst, unsigned int dst_width, unsigned int dst_height)
1024+
static inline int _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigned int src_height, gdImagePtr pDst, unsigned int dst_width, unsigned int dst_height)
10251025
{
10261026
unsigned int u;
10271027
LineContribType * contrib;
@@ -1036,13 +1036,14 @@ static inline void _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsign
10361036

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

10481049
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)
@@ -1068,7 +1069,7 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
10681069
}
10691070
}
10701071

1071-
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)
1072+
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)
10721073
{
10731074
unsigned int u;
10741075
LineContribType * contrib;
@@ -1083,19 +1084,21 @@ static inline void _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_w
10831084

10841085
contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation);
10851086
if (contrib == NULL) {
1086-
return;
1087+
return 0;
10871088
}
10881089
/* scale each column */
10891090
for (u = 0; u < dst_width - 1; u++) {
10901091
_gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib);
10911092
}
10921093
_gdContributionsFree(contrib);
1094+
return 1;
10931095
}
10941096

10951097
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)
10961098
{
10971099
gdImagePtr tmp_im;
10981100
gdImagePtr dst;
1101+
int scale_pass_res;
10991102

11001103
if (new_width == 0 || new_height == 0) {
11011104
return NULL;
@@ -1111,38 +1114,26 @@ gdImagePtr gdImageScaleTwoPass(const gdImagePtr src, const unsigned int src_widt
11111114
return NULL;
11121115
}
11131116
gdImageSetInterpolationMethod(tmp_im, src->interpolation_id);
1114-
_gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
1117+
scale_pass_res = _gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
1118+
if (scale_pass_res != 1) {
1119+
gdImageDestroy(tmp_im);
1120+
return NULL;
1121+
}
11151122

11161123
dst = gdImageCreateTrueColor(new_width, new_height);
11171124
if (dst == NULL) {
11181125
gdImageDestroy(tmp_im);
11191126
return NULL;
11201127
}
11211128
gdImageSetInterpolationMethod(dst, src->interpolation_id);
1122-
_gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
1123-
gdImageDestroy(tmp_im);
1124-
1125-
return dst;
1126-
}
1127-
1128-
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)
1129-
{
1130-
gdImagePtr tmp_im;
1131-
1132-
if (new_width == 0 || new_height == 0) {
1133-
return NULL;
1134-
}
1135-
1136-
tmp_im = gdImageCreateTrueColor(new_width, src_height);
1137-
if (tmp_im == NULL) {
1129+
scale_pass_res = _gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
1130+
if (scale_pass_res != 1) {
1131+
gdImageDestroy(dst);
1132+
gdImageDestroy(tmp_im);
11381133
return NULL;
11391134
}
1140-
gdImageSetInterpolationMethod(tmp_im, src->interpolation_id);
1141-
1142-
_gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
1143-
_gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
1144-
11451135
gdImageDestroy(tmp_im);
1136+
11461137
return dst;
11471138
}
11481139

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)