From d7b4eb9987d292f9209c655dd59ede1b226d8ba0 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 5 Jun 2024 18:49:07 +0100 Subject: [PATCH] ext/gd: imagewebp/imageavif/imagepng/imagejpeg stricter checks quality/speed. --- ext/gd/gd.c | 27 +++++++++++++++++++++++--- ext/gd/tests/avif_decode_encode.phpt | 17 ++++++++++++---- ext/gd/tests/imageresolution_jpeg.phpt | 8 ++++++++ ext/gd/tests/pngcomp.phpt | 14 ++++++++++++- ext/gd/tests/webp_basic.phpt | 7 +++++++ 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index b04bd18bb92c3..ea7aa92fe0a99 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -4108,20 +4108,36 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, switch (image_type) { #ifdef HAVE_GD_JPG case PHP_GDIMG_TYPE_JPG: + if (quality < -1 || quality > 100) { + zend_argument_value_error(3, "must be at between -1 and 100"); + ctx->gd_free(ctx); + RETURN_THROWS(); + } gdImageJpegCtx(im, ctx, (int) quality); break; #endif #ifdef HAVE_GD_WEBP case PHP_GDIMG_TYPE_WEBP: - if (quality == -1) { - quality = 80; + if (quality < -1) { + zend_argument_value_error(3, "must be greater than or equal to -1"); + ctx->gd_free(ctx); + RETURN_THROWS(); } gdImageWebpCtx(im, ctx, (int) quality); break; #endif #ifdef HAVE_GD_AVIF case PHP_GDIMG_TYPE_AVIF: - if (speed == -1) { + if (quality < -1 || quality > 100) { + zend_argument_value_error(3, "must be between -1 and 100"); + ctx->gd_free(ctx); + RETURN_THROWS(); + } + if (speed < -1 || speed > 10) { + zend_argument_value_error(4, "must be between -1 and 10"); + ctx->gd_free(ctx); + RETURN_THROWS(); + } else if (speed == -1) { speed = 6; } gdImageAvifCtx(im, ctx, (int) quality, (int) speed); @@ -4129,6 +4145,11 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, #endif #ifdef HAVE_GD_PNG case PHP_GDIMG_TYPE_PNG: + if (quality < -1 || quality > 9) { + zend_argument_value_error(3, "must be between -1 and 9"); + ctx->gd_free(ctx); + RETURN_THROWS(); + } #ifdef HAVE_GD_BUNDLED gdImagePngCtxEx(im, ctx, (int) quality, (int) basefilter); #else diff --git a/ext/gd/tests/avif_decode_encode.phpt b/ext/gd/tests/avif_decode_encode.phpt index f823f6c9967ee..cb7f1ce95a67c 100644 --- a/ext/gd/tests/avif_decode_encode.phpt +++ b/ext/gd/tests/avif_decode_encode.phpt @@ -36,10 +36,19 @@ gd echo_status(imageavif($img, $outfile, -1)); echo 'Encoding AVIF with illegal quality: '; - echo_status(imageavif($img, $outfile, 1234)); + try { + imageavif($img, $outfile, 1234); + } catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; + } echo 'Encoding AVIF with illegal speed: '; - echo_status(imageavif($img, $outfile, 70, 1234)); + + try { + imageavif($img, $outfile, 70, 1234); + } catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; + } echo 'Encoding AVIF losslessly... '; echo_status(imageavif($img, $outfile, 100, 0)); @@ -66,8 +75,8 @@ Default AVIF encoding: ok Encoding AVIF at quality 70: ok Encoding AVIF at quality 70 with speed 5: ok Encoding AVIF with default quality: ok -Encoding AVIF with illegal quality: ok -Encoding AVIF with illegal speed: ok +Encoding AVIF with illegal quality: imageavif(): Argument #3 ($quality) must be between -1 and 100 +Encoding AVIF with illegal speed: imageavif(): Argument #4 ($speed) must be between -1 and 10 Encoding AVIF losslessly... ok Decoding the AVIF we just wrote... How many pixels are different in the two images? 0 diff --git a/ext/gd/tests/imageresolution_jpeg.phpt b/ext/gd/tests/imageresolution_jpeg.phpt index cc1977e332f56..739b6949a8719 100644 --- a/ext/gd/tests/imageresolution_jpeg.phpt +++ b/ext/gd/tests/imageresolution_jpeg.phpt @@ -22,6 +22,13 @@ imageresolution($exp, 71, 299); imagejpeg($exp, $filename); $act = imagecreatefromjpeg($filename); var_dump(imageresolution($act)); +imageresolution($exp, 71, 299); + +try { + imagejpeg($exp, $filename, 101); +} catch (\ValueError $e) { + echo $e->getMessage(); +} ?> --EXPECT-- array(2) { @@ -36,6 +43,7 @@ array(2) { [1]=> int(299) } +imagejpeg(): Argument #3 ($quality) must be at between -1 and 100 --CLEAN-- getMessage() . PHP_EOL; + } + try { + imagepng($im, $cwd . '/test_pngcomp.png', 10); + } catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; + } + echo "PNG compression test: "; imagepng($im, $cwd . '/test_pngcomp.png', 9); $im2 = imagecreatefrompng($cwd . '/test_pngcomp.png'); @@ -27,4 +37,6 @@ gd @unlink($cwd . "/test_pngcomp.png"); ?> --EXPECT-- +imagepng(): Argument #3 ($quality) must be between -1 and 9 +imagepng(): Argument #3 ($quality) must be between -1 and 9 PNG compression test: ok diff --git a/ext/gd/tests/webp_basic.phpt b/ext/gd/tests/webp_basic.phpt index 65d933dcc3fda..97b0451c09b8d 100644 --- a/ext/gd/tests/webp_basic.phpt +++ b/ext/gd/tests/webp_basic.phpt @@ -37,6 +37,12 @@ $im_lossless = imagecreatefromwebp($filename); echo 'Does lossless conversion work? '; var_dump(calc_image_dissimilarity($im1, $im_lossless) == 0); +try { + imagewebp($im1, $filename, -10); +} catch (\ValueError $e) { + echo $e->getMessage(); +} + ?> --CLEAN--