From 27112853da3e2a5083fab0520d96687770537e93 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 6 Jun 2024 22:49:32 +0100 Subject: [PATCH 1/2] ext/gd: imagecrop/imageaffine checks matrix values overflow/underflow --- ext/gd/gd.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index ea7aa92fe0a99..b84ba7c8295f5 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -3504,6 +3504,7 @@ PHP_FUNCTION(imagecrop) gdRect rect; zval *z_rect; zval *tmp; + zend_long lval; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa", &IM, gd_image_ce, &z_rect) == FAILURE) { RETURN_THROWS(); @@ -3512,28 +3513,48 @@ PHP_FUNCTION(imagecrop) im = php_gd_libgdimageptr_from_zval_p(IM); if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "x", sizeof("x") -1)) != NULL) { - rect.x = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(2, "invalid \"x\" key value"); + RETURN_THROWS(); + } + rect.x = lval; } else { zend_argument_value_error(2, "must have an \"x\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "y", sizeof("y") - 1)) != NULL) { - rect.y = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(2, "invalid \"y\" key value"); + RETURN_THROWS(); + } + rect.y = lval; } else { zend_argument_value_error(2, "must have a \"y\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "width", sizeof("width") - 1)) != NULL) { - rect.width = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(2, "invalid \"width\" key value"); + RETURN_THROWS(); + } + rect.width = lval; } else { zend_argument_value_error(2, "must have a \"width\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "height", sizeof("height") - 1)) != NULL) { - rect.height = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(2, "invalid \"height\" key value"); + RETURN_THROWS(); + } + rect.height = lval; } else { zend_argument_value_error(2, "must have a \"height\" key"); RETURN_THROWS(); @@ -3695,29 +3716,50 @@ PHP_FUNCTION(imageaffine) } if (z_rect != NULL) { + zend_long lval; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "x", sizeof("x") - 1)) != NULL) { - rect.x = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(3, "invalid \"x\" key value"); + RETURN_THROWS(); + } + rect.x = lval; } else { zend_argument_value_error(3, "must have an \"x\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "y", sizeof("y") - 1)) != NULL) { - rect.y = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(3, "invalid \"y\" key value"); + RETURN_THROWS(); + } + rect.y = lval; } else { zend_argument_value_error(3, "must have a \"y\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "width", sizeof("width") - 1)) != NULL) { - rect.width = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(3, "invalid \"width\" key value"); + RETURN_THROWS(); + } + rect.width = lval; } else { zend_argument_value_error(3, "must have a \"width\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "height", sizeof("height") - 1)) != NULL) { - rect.height = zval_get_long(tmp); + lval = zval_get_long(tmp); + if (ZEND_LONG_EXCEEDS_INT(lval)) { + zend_argument_value_error(3, "invalid \"height\" key value"); + RETURN_THROWS(); + } + rect.height = lval; } else { zend_argument_value_error(3, "must have a \"height\" key"); RETURN_THROWS(); From ebaf1501d12766a7349f2b83df7f0a5415795424 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 7 Jun 2024 12:52:17 +0100 Subject: [PATCH 2/2] add test --- ext/gd/tests/imagecropaffine.phpt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ext/gd/tests/imagecropaffine.phpt diff --git a/ext/gd/tests/imagecropaffine.phpt b/ext/gd/tests/imagecropaffine.phpt new file mode 100644 index 0000000000000..0d671127feebb --- /dev/null +++ b/ext/gd/tests/imagecropaffine.phpt @@ -0,0 +1,23 @@ +--TEST-- +imagecrop/imageaffine matrix checks +--EXTENSIONS-- +gd +--FILE-- + PHP_INT_MAX, "y" => 10, "width" => 10, "height" => 105)); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + imageaffine($img, array(1, 2, 3, 4, 5, 6), array("x" => 120, "y" => 180, "width" => PHP_INT_MAX, "height" => 10)); +} catch (\ValueError $e) { + echo $e->getMessage(); +} +?> +--EXPECT-- +imagecrop(): Argument #2 ($rectangle) invalid "x" key value +imageaffine(): Argument #3 ($clip) invalid "width" key value