From 17b262ea885b1f29920146b88d342b6be1d29419 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Sun, 24 May 2026 09:39:48 -0700 Subject: [PATCH 1/4] ext/getopt.c: simplify and cleanup (#22139) Remove unneeded parentheses, adjust spacing, should be a no-op --- main/getopt.c | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/main/getopt.c b/main/getopt.c index 5f3a0085cdac..210c32152415 100644 --- a/main/getopt.c +++ b/main/getopt.c @@ -18,15 +18,14 @@ #include #include "php_getopt.h" -#define OPTERRCOLON (1) -#define OPTERRNF (2) -#define OPTERRARG (3) +#define OPTERRCOLON 1 +#define OPTERRNF 2 +#define OPTERRARG 3 // Print error message to stderr and return -2 to distinguish it from '?' command line option. static int php_opt_error(int argc, char * const *argv, int optint, int optchr, int err, int show_err) /* {{{ */ { - if (show_err) - { + if (show_err) { fprintf(stderr, "Error in argument %d, char %d: ", optint, optchr+1); switch(err) { @@ -61,7 +60,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char *optarg = NULL; } - if(prev_optarg && prev_optarg != optarg) { + if (prev_optarg && prev_optarg != optarg) { /* reset the state */ optchr = 0; dash = 0; @@ -69,20 +68,18 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char prev_optarg = optarg; if (*optind >= argc) { - return(EOF); + return EOF; } if (!dash) { - if ((argv[*optind][0] != '-')) { - return(EOF); - } else { - if (!argv[*optind][1]) - { - /* - * use to specify stdin. Need to let pgm process this and - * the following args - */ - return(EOF); - } + if (argv[*optind][0] != '-') { + return EOF; + } + if (!argv[*optind][1]) { + /* + * use to specify stdin. Need to let pgm process this and + * the following args + */ + return EOF; } } if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) { @@ -92,7 +89,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char /* '--' indicates end of args if not followed by a known long option name */ if (argv[*optind][2] == '\0') { (*optind)++; - return(EOF); + return EOF; } arg_start = 2; @@ -109,7 +106,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char php_optidx++; if (opts[php_optidx].opt_char == '-') { (*optind)++; - return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err)); + return php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err); } else if (opts[php_optidx].opt_name && !strncmp(&argv[*optind][2], opts[php_optidx].opt_name, arg_end) && arg_end == strlen(opts[php_optidx].opt_name)) { break; } @@ -127,7 +124,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char if (argv[*optind][optchr] == ':') { dash = 0; (*optind)++; - return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err)); + return php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err); } arg_start = 1 + optchr; } @@ -145,7 +142,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char optchr++; arg_start++; } - return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err)); + return php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err); } else if (argv[*optind][optchr] == opts[php_optidx].opt_char) { break; } @@ -160,7 +157,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char if (*optind == argc) { /* Was the value required or is it optional? */ if (opts[php_optidx].need_param == 1) { - return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err)); + return php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err); } /* Optional value is not supported with - style */ } else if (opts[php_optidx].need_param == 1) { @@ -178,8 +175,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char } else { /* multiple options specified as one (exclude long opts) */ if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) { - if (!argv[*optind][optchr+1]) - { + if (!argv[*optind][optchr+1]) { dash = 0; (*optind)++; } else { @@ -191,6 +187,6 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char return opts[php_optidx].opt_char; } assert(0); - return(0); /* never reached */ + return 0; /* never reached */ } /* }}} */ From 7727193818cd8e515a459dd97f854d1abbe2e66a Mon Sep 17 00:00:00 2001 From: Nora Dossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 24 May 2026 19:37:34 +0200 Subject: [PATCH 2/4] zlib: fix test skipif sections (#22099) Depending on the specific PHP configuration, the regex matching for the version number in get_zlib_version() can fail. On master, this results in deprecation warnings and subsequent test borks: ``` Deprecated: version_compare(): Passing null to parameter #1 ($version1) of type string is deprecated in /work/php-src/ext/zlib/tests/gzgetc_basic.skip.php on line 3 [/work/php-src/ext/zlib/tests/gzgetc_basic.phpt] Deprecated: version_compare(): Passing null to parameter #1 ($version1) of type string is deprecated in /work/php-src/ext/zlib/tests/gzgetc_basic_1.skip.php on line 4 ``` Since ZLIB_VERSION is a constant containing the version as a string, remove all this nonsense and just use the constant directly. --- ext/zlib/tests/bug55544-win.phpt | Bin 564 -> 532 bytes ext/zlib/tests/func.inc | 18 ------------------ ext/zlib/tests/gzencode_variation2-win32.phpt | 7 ++----- ext/zlib/tests/gzgetc_basic.phpt | 4 +--- ext/zlib/tests/gzgetc_basic_1.phpt | 4 +--- 5 files changed, 4 insertions(+), 29 deletions(-) delete mode 100644 ext/zlib/tests/func.inc diff --git a/ext/zlib/tests/bug55544-win.phpt b/ext/zlib/tests/bug55544-win.phpt index 5c94236a2f21f457485fad58085a468f96ab2e83..02a1ac8370008e4e785e99823df75894791f7549 100644 GIT binary patch delta 58 zcmdnOGKFQr9{Dr{jk46D;>`TK_~iWDg2bX!jVK>ar}!|}pkPmbzlmSHc#!#%0~sF! E0CF%C?f?J) delta 90 zcmbQjvV~>B9?QJsoYIt31@*Mjykx!1ykvE2uFNzAjk46D;>`TK_~iWDg2bX!jr7!# Z_^O=Dq (\d+\.\d+\.\d+),s', $info, $match)) { - // $version = $match[1]; - if (preg_match(',zlib(?!.*libXML).*Compiled Version (=> | --FILE-- diff --git a/ext/zlib/tests/gzgetc_basic.phpt b/ext/zlib/tests/gzgetc_basic.phpt index 7164c23098d9..3a2fbe066e91 100644 --- a/ext/zlib/tests/gzgetc_basic.phpt +++ b/ext/zlib/tests/gzgetc_basic.phpt @@ -4,9 +4,7 @@ Test function gzgetc() by calling it with its expected arguments zlib 1.2.5 zlib --SKIPIF-- 0) { +if (version_compare(ZLIB_VERSION, '1.2.5') > 0) { die('skip - only for zlib <= 1.2.5'); } ?> diff --git a/ext/zlib/tests/gzgetc_basic_1.phpt b/ext/zlib/tests/gzgetc_basic_1.phpt index e70c5814fcbc..91c3a7638574 100644 --- a/ext/zlib/tests/gzgetc_basic_1.phpt +++ b/ext/zlib/tests/gzgetc_basic_1.phpt @@ -4,9 +4,7 @@ Test function gzgetc() by calling it with its expected arguments zlib 1.2.7 zlib --SKIPIF-- = 1.2.7'); } ?> From ec8342c2227e46dc3b818d591dce9b8072fe3a1e Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 22 May 2026 18:34:25 +0100 Subject: [PATCH 3/4] Fix GH-19666: imageconvolution() unexpected nan filter value. undefined behavior occurs during cast from float to int when the element of the filter matrix is -INF. Port the libgd clamp helper which treats non-finite accumulators as 0 (negative/NaN) or 255 (positive infinity) instead of bailing out, matching upstream libgd 81d7f2e. close GH-22129 --- NEWS | 2 ++ ext/gd/libgd/gd_filter.c | 26 +++++++++++++++++++++----- ext/gd/tests/gh19666.phpt | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 ext/gd/tests/gh19666.phpt diff --git a/NEWS b/NEWS index 460156172cae..db03aa98c3a1 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - GD: . Fixed bug GH-22121 (Double free in gdImageSetStyle() after overflow-triggered early return). (iliaal) + . Fixed bug GH-19666 (imageconvolution() unexpected nan filter value). + (David Carlier) - Intl: . Fix incorrect argument positions for uninitialized calendar arguments in diff --git a/ext/gd/libgd/gd_filter.c b/ext/gd/libgd/gd_filter.c index db364c923ec6..201a0a8630f1 100644 --- a/ext/gd/libgd/gd_filter.c +++ b/ext/gd/libgd/gd_filter.c @@ -7,6 +7,7 @@ #else # include #endif +#include #include #include @@ -20,6 +21,20 @@ /* Begin filters function */ #define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel) +static int gdClampFloatToByte(float value) +{ + if (!isfinite(value)) { + return value > 0.0f ? 255 : 0; + } + if (value > 255.0f) { + return 255; + } + if (value < 0.0f) { + return 0; + } + return (int)value; +} + #ifdef _WIN32 # define GD_SCATTER_SEED() (unsigned int)(time(0) * GetCurrentProcessId()) #else @@ -361,6 +376,7 @@ int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, flo for ( y=0; ysy; y++) { for(x=0; xsx; x++) { + int new_ri, new_gi, new_bi; new_r = new_g = new_b = 0; pxl = f(srcback, x, y); new_a = gdImageAlpha(srcback, pxl); @@ -379,13 +395,13 @@ int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, flo new_g = (new_g/filter_div)+offset; new_b = (new_b/filter_div)+offset; - new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r); - new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g); - new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b); + new_ri = gdClampFloatToByte(new_r); + new_gi = gdClampFloatToByte(new_g); + new_bi = gdClampFloatToByte(new_b); - new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + new_pxl = gdImageColorAllocateAlpha(src, new_ri, new_gi, new_bi, new_a); if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + new_pxl = gdImageColorClosestAlpha(src, new_ri, new_gi, new_bi, new_a); } gdImageSetPixel (src, x, y, new_pxl); } diff --git a/ext/gd/tests/gh19666.phpt b/ext/gd/tests/gh19666.phpt new file mode 100644 index 000000000000..2d82b9b44760 --- /dev/null +++ b/ext/gd/tests/gh19666.phpt @@ -0,0 +1,34 @@ +--TEST-- +GH-19666 (Unexpected nan value in imageconvolution) +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +bool(true) +array(4) { + ["red"]=> + int(0) + ["green"]=> + int(0) + ["blue"]=> + int(0) + ["alpha"]=> + int(0) +} From 7500c86b15ea00bfe9b3ad1d288aa0214248e3b7 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 24 May 2026 20:50:12 +0100 Subject: [PATCH 4/4] ext/intl: fix deprecation warning for GH-19666 test. --- ext/gd/tests/gh19666.phpt | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/gd/tests/gh19666.phpt b/ext/gd/tests/gh19666.phpt index 2d82b9b44760..ba9bf54f5661 100644 --- a/ext/gd/tests/gh19666.phpt +++ b/ext/gd/tests/gh19666.phpt @@ -17,8 +17,6 @@ var_dump(imageconvolution($image, $gaussian, 16, 0)); $rgba = imagecolorat($image, 0, 0); $colors = imagecolorsforindex($image, $rgba); var_dump($colors); - -imagedestroy($image); ?> --EXPECT-- bool(true)