diff --git a/NEWS b/NEWS index afdeb8e2378..d51561dd8e9 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,9 @@ PHP NEWS - Core: . Fixed bug GH-14801 (Fix build for armv7). (andypost) +- GD: + . Check overflow/underflow for imagescale/imagefilter. (David Carlier) + - LibXML: . Added LIBXML_NO_XXE constant. (nielsdos) diff --git a/UPGRADING b/UPGRADING index dc3cf65a205..1bfe0297857 100644 --- a/UPGRADING +++ b/UPGRADING @@ -442,6 +442,10 @@ PHP 8.4 UPGRADE NOTES . imagejpeg/imagewebp/imagepng/imageavif throws an exception if an invalid quality parameter value is passed. In addition, imageavif will throw an exception if an invalid speed parameter value is passed. + . imagescale throws an exception if the width/height argument underflows/overflows or + if the mode argument is invalid. + imagefilter with IMG_FILTER_SCATTER throws an exception if the sub/plus arguments + underflows/overflows. - Gettext: . bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception diff --git a/ext/gd/gd.c b/ext/gd/gd.c index bd14b3af8a5..4731eff7411 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -3645,6 +3645,16 @@ static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS) Z_PARAM_ARRAY(hash_colors) ZEND_PARSE_PARAMETERS_END(); + if (scatter_sub < 0 || ZEND_SIZE_T_INT_OVFL(scatter_sub)) { + zend_argument_value_error(3, "must be between 0 and %d", INT_MAX); + RETURN_THROWS(); + } + + if (scatter_plus < 0 || ZEND_SIZE_T_INT_OVFL(scatter_plus)) { + zend_argument_value_error(4, "must be between 0 and %d", INT_MAX); + RETURN_THROWS(); + } + im = php_gd_libgdimageptr_from_zval_p(IM); if (hash_colors) { @@ -3939,6 +3949,12 @@ PHP_FUNCTION(imagescale) Z_PARAM_LONG(tmp_h) Z_PARAM_LONG(tmp_m) ZEND_PARSE_PARAMETERS_END(); + + if (tmp_m < GD_DEFAULT || tmp_m >= GD_METHOD_COUNT) { + zend_argument_value_error(4, "must be one of the GD_* constants"); + RETURN_THROWS(); + } + method = tmp_m; im = php_gd_libgdimageptr_from_zval_p(IM); @@ -3958,10 +3974,17 @@ PHP_FUNCTION(imagescale) } } - if (tmp_h <= 0 || tmp_h > INT_MAX || tmp_w <= 0 || tmp_w > INT_MAX) { - RETURN_FALSE; + if (tmp_w <= 0 || ZEND_SIZE_T_INT_OVFL(tmp_w)) { + zend_argument_value_error(2, "must be between 1 and %d", INT_MAX); + RETURN_THROWS(); } + if (tmp_h <= 0 || ZEND_SIZE_T_INT_OVFL(tmp_h)) { + zend_argument_value_error(3, "must be between 1 and %d", INT_MAX); + RETURN_THROWS(); + } + + new_width = tmp_w; new_height = tmp_h; diff --git a/ext/gd/tests/bug72337.phpt b/ext/gd/tests/bug72337.phpt index dab2f32a5c1..a15fa349304 100644 --- a/ext/gd/tests/bug72337.phpt +++ b/ext/gd/tests/bug72337.phpt @@ -5,8 +5,26 @@ gd --FILE-- getMessage() . PHP_EOL; +} +try { + imagescale($im, 0, 1, 0); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagescale($im, 1, 0, 0); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +imagescale($im, 1, 1, IMG_BICUBIC_FIXED); echo "OK"; ?> --EXPECT-- +imagescale(): Argument #4 ($mode) must be one of the GD_* constants +imagescale(): Argument #2 ($width) must be between 1 and 2147483647 +imagescale(): Argument #3 ($height) must be between 1 and 2147483647 OK diff --git a/ext/gd/tests/bug73957.phpt b/ext/gd/tests/bug73957.phpt index b754d16377e..067d71674eb 100644 --- a/ext/gd/tests/bug73957.phpt +++ b/ext/gd/tests/bug73957.phpt @@ -9,11 +9,14 @@ if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only'); --FILE-- getMessage(); } ?> ---EXPECT-- -bool(false) +--EXPECTF-- +imagescale(): Argument #2 ($width) must be between 1 and %d diff --git a/ext/gd/tests/imagefilter.phpt b/ext/gd/tests/imagefilter.phpt index c8cf182d9d4..485b08d4bfe 100644 --- a/ext/gd/tests/imagefilter.phpt +++ b/ext/gd/tests/imagefilter.phpt @@ -95,7 +95,7 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png"; echo "IMG_FILTER_SCATTER failed\n"; } ?> ---EXPECT-- +--EXPECTF-- IMG_FILTER_NEGATE success IMG_FILTER_GRAYSCALE success IMG_FILTER_EDGEDETECT success diff --git a/ext/gd/tests/imagefilter2.phpt b/ext/gd/tests/imagefilter2.phpt new file mode 100644 index 00000000000..99b73ffc133 --- /dev/null +++ b/ext/gd/tests/imagefilter2.phpt @@ -0,0 +1,36 @@ +--TEST-- +imagefilter() function test +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- +getMessage() . PHP_EOL; + } + try { + imagefilter($im, IMG_FILTER_SCATTER, 0, $val); + } catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; + } +} +?> +--EXPECTF-- +imagefilter(): Argument #3 must be between 0 and %d +imagefilter(): Argument #4 must be between 0 and %d +imagefilter(): Argument #3 must be between 0 and %d +imagefilter(): Argument #4 must be between 0 and %d