Skip to content

Commit

Permalink
ext/gd: checking imagescale/imagefilter invalid values.
Browse files Browse the repository at this point in the history
close GH-14598
  • Loading branch information
devnexen committed Jul 8, 2024
1 parent 8825235 commit 23a55ba
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 10 deletions.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 4 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 25 additions & 2 deletions ext/gd/gd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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;

Expand Down
20 changes: 19 additions & 1 deletion ext/gd/tests/bug72337.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,26 @@ gd
--FILE--
<?php
$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";
?>
--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
15 changes: 9 additions & 6 deletions ext/gd/tests/bug73957.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only');
--FILE--
<?php
$im = imagecreate(8, 8);
$im = imagescale($im, 0x100000001, 1);
var_dump($im);
if ($im) { // which is not supposed to happen
var_dump(imagesx($im));

try {
$im = imagescale($im, 0x100000001, 1);
// which is not supposed to happen
var_dump(imagesx($im));
} catch (\ValueError $e) {
echo $e->getMessage();
}
?>
--EXPECT--
bool(false)
--EXPECTF--
imagescale(): Argument #2 ($width) must be between 1 and %d
2 changes: 1 addition & 1 deletion ext/gd/tests/imagefilter.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 36 additions & 0 deletions ext/gd/tests/imagefilter2.phpt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 23a55ba

Please sign in to comment.