From 5d21e92d8eaba80e6fb2cd82079c670390656178 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 16 Jun 2024 15:48:30 +0100 Subject: [PATCH 1/3] ext/gd: iamgeresolution checks overflow. also gd updates the resolution only if x/y are > 0. --- ext/gd/gd.c | 16 +++++++++++++ ext/gd/tests/imageresolution_basic.phpt | 30 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 ext/gd/tests/imageresolution_basic.phpt diff --git a/ext/gd/gd.c b/ext/gd/gd.c index b655f13296cff..d301bebf8368d 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -4282,12 +4282,28 @@ PHP_FUNCTION(imageresolution) im = php_gd_libgdimageptr_from_zval_p(IM); if (!res_x_is_null && !res_y_is_null) { + if (ZEND_SIZE_T_UINT_OVFL(res_x)) { + zend_argument_value_error(2, "must be lower than %u", UINT_MAX); + RETURN_THROWS(); + } + if (ZEND_SIZE_T_UINT_OVFL(res_y)) { + zend_argument_value_error(3, "must be lower than %u", UINT_MAX); + RETURN_THROWS(); + } gdImageSetResolution(im, res_x, res_y); RETURN_TRUE; } else if (!res_x_is_null && res_y_is_null) { + if (ZEND_SIZE_T_UINT_OVFL(res_x)) { + zend_argument_value_error(2, "must be lower than %u", UINT_MAX); + RETURN_THROWS(); + } gdImageSetResolution(im, res_x, res_x); RETURN_TRUE; } else if (res_x_is_null && !res_y_is_null) { + if (ZEND_SIZE_T_UINT_OVFL(res_y)) { + zend_argument_value_error(3, "must be lower than %u", UINT_MAX); + RETURN_THROWS(); + } gdImageSetResolution(im, res_y, res_y); RETURN_TRUE; } diff --git a/ext/gd/tests/imageresolution_basic.phpt b/ext/gd/tests/imageresolution_basic.phpt new file mode 100644 index 0000000000000..579c4ddffc62d --- /dev/null +++ b/ext/gd/tests/imageresolution_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +Wrong image resolution +--EXTENSIONS-- +gd +--FILE-- +getMessage() . PHP_EOL; +} +try { + imageresolution($exp, 127, -PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +imageresolution($exp, 0, 0); +var_dump(imageresolution($exp) == $res); +?> +--EXPECTF-- +imageresolution(): Argument #2 ($resolution_x) must be lower than %d +imageresolution(): Argument #3 ($resolution_y) must be lower than %d +bool(true) From 6a79fd467f91ce50aa051a401acb1132fe45133b Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 16 Jun 2024 16:06:25 +0100 Subject: [PATCH 2/3] fix test --- ext/gd/tests/imageresolution_basic.phpt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/gd/tests/imageresolution_basic.phpt b/ext/gd/tests/imageresolution_basic.phpt index 579c4ddffc62d..adca5919039ab 100644 --- a/ext/gd/tests/imageresolution_basic.phpt +++ b/ext/gd/tests/imageresolution_basic.phpt @@ -2,6 +2,10 @@ Wrong image resolution --EXTENSIONS-- gd +--SKIPIF-- + --FILE-- Date: Sun, 16 Jun 2024 20:14:30 +0100 Subject: [PATCH 3/3] changes from feedback --- ext/gd/gd.c | 16 ++++++++-------- ext/gd/tests/imageresolution_basic.phpt | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index d301bebf8368d..eb282ec232816 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -4282,26 +4282,26 @@ PHP_FUNCTION(imageresolution) im = php_gd_libgdimageptr_from_zval_p(IM); if (!res_x_is_null && !res_y_is_null) { - if (ZEND_SIZE_T_UINT_OVFL(res_x)) { - zend_argument_value_error(2, "must be lower than %u", UINT_MAX); + if (res_x < 0 || ZEND_SIZE_T_UINT_OVFL(res_x)) { + zend_argument_value_error(2, "must be between 0 and %u", UINT_MAX); RETURN_THROWS(); } - if (ZEND_SIZE_T_UINT_OVFL(res_y)) { - zend_argument_value_error(3, "must be lower than %u", UINT_MAX); + if (res_y < 0 || ZEND_SIZE_T_UINT_OVFL(res_y)) { + zend_argument_value_error(3, "must be between 0 and %u", UINT_MAX); RETURN_THROWS(); } gdImageSetResolution(im, res_x, res_y); RETURN_TRUE; } else if (!res_x_is_null && res_y_is_null) { - if (ZEND_SIZE_T_UINT_OVFL(res_x)) { - zend_argument_value_error(2, "must be lower than %u", UINT_MAX); + if (res_x < 0 || ZEND_SIZE_T_UINT_OVFL(res_x)) { + zend_argument_value_error(2, "must be between 0 and %u", UINT_MAX); RETURN_THROWS(); } gdImageSetResolution(im, res_x, res_x); RETURN_TRUE; } else if (res_x_is_null && !res_y_is_null) { - if (ZEND_SIZE_T_UINT_OVFL(res_y)) { - zend_argument_value_error(3, "must be lower than %u", UINT_MAX); + if (res_y < 0 || ZEND_SIZE_T_UINT_OVFL(res_y)) { + zend_argument_value_error(3, "must be between 0 and %u", UINT_MAX); RETURN_THROWS(); } gdImageSetResolution(im, res_y, res_y); diff --git a/ext/gd/tests/imageresolution_basic.phpt b/ext/gd/tests/imageresolution_basic.phpt index adca5919039ab..74dc8c59dcda5 100644 --- a/ext/gd/tests/imageresolution_basic.phpt +++ b/ext/gd/tests/imageresolution_basic.phpt @@ -29,6 +29,6 @@ imageresolution($exp, 0, 0); var_dump(imageresolution($exp) == $res); ?> --EXPECTF-- -imageresolution(): Argument #2 ($resolution_x) must be lower than %d -imageresolution(): Argument #3 ($resolution_y) must be lower than %d +imageresolution(): Argument #2 ($resolution_x) must be between 0 and %d +imageresolution(): Argument #3 ($resolution_y) must be between 0 and %d bool(true)