ext/gd: checking imagescale/imagefilter invalid values.

close GH-14598
This commit is contained in:
David Carlier 2024-06-18 19:27:58 +01:00
parent 8825235348
commit 23a55babb4
No known key found for this signature in database
GPG key ID: D308BD11AB42D054
7 changed files with 97 additions and 10 deletions

3
NEWS
View file

@ -5,6 +5,9 @@ PHP NEWS
- Core: - Core:
. Fixed bug GH-14801 (Fix build for armv7). (andypost) . Fixed bug GH-14801 (Fix build for armv7). (andypost)
- GD:
. Check overflow/underflow for imagescale/imagefilter. (David Carlier)
- LibXML: - LibXML:
. Added LIBXML_NO_XXE constant. (nielsdos) . Added LIBXML_NO_XXE constant. (nielsdos)

View file

@ -442,6 +442,10 @@ PHP 8.4 UPGRADE NOTES
. imagejpeg/imagewebp/imagepng/imageavif throws an exception if an invalid . imagejpeg/imagewebp/imagepng/imageavif throws an exception if an invalid
quality parameter value is passed. In addition, imageavif will throw an exception quality parameter value is passed. In addition, imageavif will throw an exception
if an invalid speed parameter value is passed. 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: - Gettext:
. bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception . bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception

View file

@ -3645,6 +3645,16 @@ static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS)
Z_PARAM_ARRAY(hash_colors) Z_PARAM_ARRAY(hash_colors)
ZEND_PARSE_PARAMETERS_END(); 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); im = php_gd_libgdimageptr_from_zval_p(IM);
if (hash_colors) { if (hash_colors) {
@ -3939,6 +3949,12 @@ PHP_FUNCTION(imagescale)
Z_PARAM_LONG(tmp_h) Z_PARAM_LONG(tmp_h)
Z_PARAM_LONG(tmp_m) Z_PARAM_LONG(tmp_m)
ZEND_PARSE_PARAMETERS_END(); 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; method = tmp_m;
im = php_gd_libgdimageptr_from_zval_p(IM); 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) { if (tmp_w <= 0 || ZEND_SIZE_T_INT_OVFL(tmp_w)) {
RETURN_FALSE; 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_width = tmp_w;
new_height = tmp_h; new_height = tmp_h;

View file

@ -5,8 +5,26 @@ gd
--FILE-- --FILE--
<?php <?php
$im = imagecreatetruecolor(1, 1); $im = imagecreatetruecolor(1, 1);
imagescale($im, 0, 0, IMG_BICUBIC_FIXED); try {
imagescale($im, 1, 1, -10);
} catch (\ValueError $e) {
echo $e->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"; echo "OK";
?> ?>
--EXPECT-- --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 OK

View file

@ -9,11 +9,14 @@ if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only');
--FILE-- --FILE--
<?php <?php
$im = imagecreate(8, 8); $im = imagecreate(8, 8);
$im = imagescale($im, 0x100000001, 1);
var_dump($im); try {
if ($im) { // which is not supposed to happen $im = imagescale($im, 0x100000001, 1);
// which is not supposed to happen
var_dump(imagesx($im)); var_dump(imagesx($im));
} catch (\ValueError $e) {
echo $e->getMessage();
} }
?> ?>
--EXPECT-- --EXPECTF--
bool(false) imagescale(): Argument #2 ($width) must be between 1 and %d

View file

@ -95,7 +95,7 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png";
echo "IMG_FILTER_SCATTER failed\n"; echo "IMG_FILTER_SCATTER failed\n";
} }
?> ?>
--EXPECT-- --EXPECTF--
IMG_FILTER_NEGATE success IMG_FILTER_NEGATE success
IMG_FILTER_GRAYSCALE success IMG_FILTER_GRAYSCALE success
IMG_FILTER_EDGEDETECT success IMG_FILTER_EDGEDETECT success

View file

@ -0,0 +1,36 @@
--TEST--
imagefilter() function test
--EXTENSIONS--
gd
--SKIPIF--
<?php
if (PHP_INT_SIZE != 8) die("skip only for 64 bits platforms");
if (!function_exists("imagefilter")) die("skip requires imagefilter function");
if (!(imagetypes() & IMG_PNG)) {
die("skip No PNG support");
}
?>
--FILE--
<?php
$SAVE_DIR = __DIR__;
$SOURCE_IMG = $SAVE_DIR . "/test.png";
$im = imagecreatefrompng($SOURCE_IMG);
foreach ([-1, PHP_INT_MAX] as $val) {
try {
imagefilter($im, IMG_FILTER_SCATTER, $val, 0);
} catch (\ValueError $e) {
echo $e->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