Skip to content

Commit 3645a3c

Browse files
committed
fix imagecrop overflow
1 parent 3fb7d75 commit 3645a3c

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

ext/gd/gd.c

+15-5
Original file line numberDiff line numberDiff line change
@@ -3848,7 +3848,7 @@ PHP_FUNCTION(imageantialias)
38483848
}
38493849
/* }}} */
38503850

3851-
static bool _php_gd_zval_try_get_c_int(zval *tmp, const char *field, int *res) {
3851+
static bool php_gd_zval_try_get_c_int(zval *tmp, const char *field, int *res) {
38523852
zend_long r;
38533853
bool failed = false;
38543854
r = zval_try_get_long(tmp, &failed);
@@ -3882,7 +3882,7 @@ PHP_FUNCTION(imagecrop)
38823882
im = php_gd_libgdimageptr_from_zval_p(IM);
38833883

38843884
if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "x", sizeof("x") -1)) != NULL) {
3885-
if (!_php_gd_zval_try_get_c_int(tmp, "x", &rect.x)) {
3885+
if (!php_gd_zval_try_get_c_int(tmp, "x", &rect.x)) {
38863886
RETURN_THROWS();
38873887
}
38883888
} else {
@@ -3891,7 +3891,7 @@ PHP_FUNCTION(imagecrop)
38913891
}
38923892

38933893
if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "y", sizeof("y") - 1)) != NULL) {
3894-
if (!_php_gd_zval_try_get_c_int(tmp, "y", &rect.y)) {
3894+
if (!php_gd_zval_try_get_c_int(tmp, "y", &rect.y)) {
38953895
RETURN_THROWS();
38963896
}
38973897
} else {
@@ -3900,7 +3900,7 @@ PHP_FUNCTION(imagecrop)
39003900
}
39013901

39023902
if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "width", sizeof("width") - 1)) != NULL) {
3903-
if (!_php_gd_zval_try_get_c_int(tmp, "width", &rect.width)) {
3903+
if (!php_gd_zval_try_get_c_int(tmp, "width", &rect.width)) {
39043904
RETURN_THROWS();
39053905
}
39063906
} else {
@@ -3909,14 +3909,24 @@ PHP_FUNCTION(imagecrop)
39093909
}
39103910

39113911
if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "height", sizeof("height") - 1)) != NULL) {
3912-
if (!_php_gd_zval_try_get_c_int(tmp, "height", &rect.height)) {
3912+
if (!php_gd_zval_try_get_c_int(tmp, "height", &rect.height)) {
39133913
RETURN_THROWS();
39143914
}
39153915
} else {
39163916
zend_argument_value_error(2, "must have a \"height\" key");
39173917
RETURN_THROWS();
39183918
}
39193919

3920+
if ((rect.width > 0 && rect.x > INT_MAX - rect.width) || (rect.width < 0 && rect.x < INT_MIN - rect.width)) {
3921+
zend_argument_value_error(2, "overflow with \"x\" and \"width\" keys");
3922+
RETURN_THROWS();
3923+
}
3924+
3925+
if ((rect.height > 0 && rect.y > INT_MAX - rect.height) || (rect.height < 0 && rect.y < INT_MIN - rect.height)) {
3926+
zend_argument_value_error(2, "overflow with \"y\" and \"height\" keys");
3927+
RETURN_THROWS();
3928+
}
3929+
39203930
im_crop = gdImageCrop(im, &rect);
39213931

39223932
if (im_crop == NULL) {

ext/gd/tests/bug66356.phpt

+8-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ $img = imagecreatetruecolor(10, 10);
1010
var_dump(imagecrop($img, array("x" => 0, "y" => 0, "width" => 10, "height" => 10)));
1111

1212
$arr = array("x" => 2147483647, "y" => 2147483647, "width" => 10, "height" => 10);
13-
var_dump(imagecrop($img, $arr));
13+
try {
14+
imagecrop($img, $arr);
15+
} catch (\ValueError $e) {
16+
echo $e->getMessage() . PHP_EOL;
17+
}
1418
print_r($arr);
1519

1620
// POC #2
@@ -28,8 +32,7 @@ var_dump(imagecrop($img, array("x" => 0, "y" => 0, "width" => 65535, "height" =>
2832
--EXPECTF--
2933
object(GdImage)#2 (0) {
3034
}
31-
object(GdImage)#2 (0) {
32-
}
35+
imagecrop(): Argument #2 ($rectangle) overflow with "x" and "width" keys
3336
Array
3437
(
3538
[x] => 2147483647
@@ -41,9 +44,9 @@ Array
4144
Warning: imagecrop(): %cne parameter to a memory allocation multiplication is negative or zero, failing operation gracefully
4245
in %s on line %d
4346
bool(false)
44-
object(GdImage)#2 (0) {
47+
object(GdImage)#3 (0) {
4548
}
46-
object(GdImage)#2 (0) {
49+
object(GdImage)#3 (0) {
4750
}
4851

4952
Warning: imagecrop(): %croduct of memory allocation multiplication would exceed INT_MAX, failing operation gracefully

0 commit comments

Comments
 (0)