Skip to content

Commit 23a55ba

Browse files
committed
ext/gd: checking imagescale/imagefilter invalid values.
close GH-14598
1 parent 8825235 commit 23a55ba

File tree

7 files changed

+97
-10
lines changed

7 files changed

+97
-10
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ PHP NEWS
55
- Core:
66
. Fixed bug GH-14801 (Fix build for armv7). (andypost)
77

8+
- GD:
9+
. Check overflow/underflow for imagescale/imagefilter. (David Carlier)
10+
811
- LibXML:
912
. Added LIBXML_NO_XXE constant. (nielsdos)
1013

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ PHP 8.4 UPGRADE NOTES
442442
. imagejpeg/imagewebp/imagepng/imageavif throws an exception if an invalid
443443
quality parameter value is passed. In addition, imageavif will throw an exception
444444
if an invalid speed parameter value is passed.
445+
. imagescale throws an exception if the width/height argument underflows/overflows or
446+
if the mode argument is invalid.
447+
imagefilter with IMG_FILTER_SCATTER throws an exception if the sub/plus arguments
448+
underflows/overflows.
445449

446450
- Gettext:
447451
. bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception

ext/gd/gd.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3645,6 +3645,16 @@ static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS)
36453645
Z_PARAM_ARRAY(hash_colors)
36463646
ZEND_PARSE_PARAMETERS_END();
36473647

3648+
if (scatter_sub < 0 || ZEND_SIZE_T_INT_OVFL(scatter_sub)) {
3649+
zend_argument_value_error(3, "must be between 0 and %d", INT_MAX);
3650+
RETURN_THROWS();
3651+
}
3652+
3653+
if (scatter_plus < 0 || ZEND_SIZE_T_INT_OVFL(scatter_plus)) {
3654+
zend_argument_value_error(4, "must be between 0 and %d", INT_MAX);
3655+
RETURN_THROWS();
3656+
}
3657+
36483658
im = php_gd_libgdimageptr_from_zval_p(IM);
36493659

36503660
if (hash_colors) {
@@ -3939,6 +3949,12 @@ PHP_FUNCTION(imagescale)
39393949
Z_PARAM_LONG(tmp_h)
39403950
Z_PARAM_LONG(tmp_m)
39413951
ZEND_PARSE_PARAMETERS_END();
3952+
3953+
if (tmp_m < GD_DEFAULT || tmp_m >= GD_METHOD_COUNT) {
3954+
zend_argument_value_error(4, "must be one of the GD_* constants");
3955+
RETURN_THROWS();
3956+
}
3957+
39423958
method = tmp_m;
39433959

39443960
im = php_gd_libgdimageptr_from_zval_p(IM);
@@ -3958,10 +3974,17 @@ PHP_FUNCTION(imagescale)
39583974
}
39593975
}
39603976

3961-
if (tmp_h <= 0 || tmp_h > INT_MAX || tmp_w <= 0 || tmp_w > INT_MAX) {
3962-
RETURN_FALSE;
3977+
if (tmp_w <= 0 || ZEND_SIZE_T_INT_OVFL(tmp_w)) {
3978+
zend_argument_value_error(2, "must be between 1 and %d", INT_MAX);
3979+
RETURN_THROWS();
39633980
}
39643981

3982+
if (tmp_h <= 0 || ZEND_SIZE_T_INT_OVFL(tmp_h)) {
3983+
zend_argument_value_error(3, "must be between 1 and %d", INT_MAX);
3984+
RETURN_THROWS();
3985+
}
3986+
3987+
39653988
new_width = tmp_w;
39663989
new_height = tmp_h;
39673990

ext/gd/tests/bug72337.phpt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,26 @@ gd
55
--FILE--
66
<?php
77
$im = imagecreatetruecolor(1, 1);
8-
imagescale($im, 0, 0, IMG_BICUBIC_FIXED);
8+
try {
9+
imagescale($im, 1, 1, -10);
10+
} catch (\ValueError $e) {
11+
echo $e->getMessage() . PHP_EOL;
12+
}
13+
try {
14+
imagescale($im, 0, 1, 0);
15+
} catch (\ValueError $e) {
16+
echo $e->getMessage() . PHP_EOL;
17+
}
18+
try {
19+
imagescale($im, 1, 0, 0);
20+
} catch (\ValueError $e) {
21+
echo $e->getMessage() . PHP_EOL;
22+
}
23+
imagescale($im, 1, 1, IMG_BICUBIC_FIXED);
924
echo "OK";
1025
?>
1126
--EXPECT--
27+
imagescale(): Argument #4 ($mode) must be one of the GD_* constants
28+
imagescale(): Argument #2 ($width) must be between 1 and 2147483647
29+
imagescale(): Argument #3 ($height) must be between 1 and 2147483647
1230
OK

ext/gd/tests/bug73957.phpt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only');
99
--FILE--
1010
<?php
1111
$im = imagecreate(8, 8);
12-
$im = imagescale($im, 0x100000001, 1);
13-
var_dump($im);
14-
if ($im) { // which is not supposed to happen
15-
var_dump(imagesx($im));
12+
13+
try {
14+
$im = imagescale($im, 0x100000001, 1);
15+
// which is not supposed to happen
16+
var_dump(imagesx($im));
17+
} catch (\ValueError $e) {
18+
echo $e->getMessage();
1619
}
1720
?>
18-
--EXPECT--
19-
bool(false)
21+
--EXPECTF--
22+
imagescale(): Argument #2 ($width) must be between 1 and %d

ext/gd/tests/imagefilter.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png";
9595
echo "IMG_FILTER_SCATTER failed\n";
9696
}
9797
?>
98-
--EXPECT--
98+
--EXPECTF--
9999
IMG_FILTER_NEGATE success
100100
IMG_FILTER_GRAYSCALE success
101101
IMG_FILTER_EDGEDETECT success

ext/gd/tests/imagefilter2.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
imagefilter() function test
3+
--EXTENSIONS--
4+
gd
5+
--SKIPIF--
6+
<?php
7+
if (PHP_INT_SIZE != 8) die("skip only for 64 bits platforms");
8+
if (!function_exists("imagefilter")) die("skip requires imagefilter function");
9+
if (!(imagetypes() & IMG_PNG)) {
10+
die("skip No PNG support");
11+
}
12+
?>
13+
--FILE--
14+
<?php
15+
$SAVE_DIR = __DIR__;
16+
$SOURCE_IMG = $SAVE_DIR . "/test.png";
17+
$im = imagecreatefrompng($SOURCE_IMG);
18+
19+
foreach ([-1, PHP_INT_MAX] as $val) {
20+
try {
21+
imagefilter($im, IMG_FILTER_SCATTER, $val, 0);
22+
} catch (\ValueError $e) {
23+
echo $e->getMessage() . PHP_EOL;
24+
}
25+
try {
26+
imagefilter($im, IMG_FILTER_SCATTER, 0, $val);
27+
} catch (\ValueError $e) {
28+
echo $e->getMessage() . PHP_EOL;
29+
}
30+
}
31+
?>
32+
--EXPECTF--
33+
imagefilter(): Argument #3 must be between 0 and %d
34+
imagefilter(): Argument #4 must be between 0 and %d
35+
imagefilter(): Argument #3 must be between 0 and %d
36+
imagefilter(): Argument #4 must be between 0 and %d

0 commit comments

Comments
 (0)