From ee6972302d2c16d9b0e057a2b19b06646db73be7 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 13:48:55 +0000 Subject: [PATCH 1/9] main/SAPI.c: header_register_callback() always returns true --- ext/standard/basic_functions.stub.php | 2 +- ext/standard/basic_functions_arginfo.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 7913ca0e00194..a4e235fd37409 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1491,7 +1491,7 @@ function set_time_limit(int $seconds): bool {} /* main/SAPI.c */ -function header_register_callback(callable $callback): bool {} +function header_register_callback(callable $callback): true {} /* main/output.c */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 0a21d7d76426c..437ecf8ccd634 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,11 +1,11 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f6bf6cdd07080c01d3a0cb08d71409d05b1084f9 */ + * Stub hash: f578c888fc5302f209e150bad1f1ce6e4107465b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_header_register_callback, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_header_register_callback, 0, 1, IS_TRUE, 0) ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) ZEND_END_ARG_INFO() From e0c3cc6ca45d6665686c17945d96a8f27b7a427a Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 13:49:40 +0000 Subject: [PATCH 2/9] main/output.c: use RETURN_BOOL() when possible --- main/output.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/main/output.c b/main/output.c index 653b457e9b641..01066cadbc2b1 100644 --- a/main/output.c +++ b/main/output.c @@ -1593,11 +1593,7 @@ PHP_FUNCTION(output_reset_rewrite_vars) RETURN_THROWS(); } - if (php_url_scanner_reset_vars() == SUCCESS) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(php_url_scanner_reset_vars() == SUCCESS); } /* }}} */ @@ -1611,10 +1607,6 @@ PHP_FUNCTION(output_add_rewrite_var) RETURN_THROWS(); } - if (php_url_scanner_add_var(name, name_len, value, value_len, 1) == SUCCESS) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(php_url_scanner_add_var(name, name_len, value, value_len, 1) == SUCCESS); } /* }}} */ From 3d9cca4db4762b76f2164d29a68418e90ad98e87 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 14:22:38 +0000 Subject: [PATCH 3/9] ext/standard/head.c: use RETURN_BOOL() when possible --- ext/standard/head.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ext/standard/head.c b/ext/standard/head.c index 76ba89dc01713..797d8d66c56ae 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -260,11 +260,7 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw) } } - if (php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, partitioned, !is_raw) == SUCCESS) { - RETVAL_TRUE; - } else { - RETVAL_FALSE; - } + RETVAL_BOOL(php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, partitioned, !is_raw) == SUCCESS); if (options) { cleanup: @@ -328,11 +324,7 @@ PHP_FUNCTION(headers_sent) break; } - if (SG(headers_sent)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(SG(headers_sent)); } /* }}} */ From dd0156eaa9add6f8528c8dcc25dd403714e2c473 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 14:06:55 +0000 Subject: [PATCH 4/9] ext/standard/basic_functions.c: use RETURN_BOOL() when possible --- ext/standard/basic_functions.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index e0c4230dae27c..07ec0d8242ae6 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1342,11 +1342,7 @@ PHP_FUNCTION(error_log) Z_PARAM_STRING_OR_NULL(headers, headers_len) ZEND_PARSE_PARAMETERS_END(); - if (_php_error_log_ex((int) erropt, message, message_len, opt, headers) == FAILURE) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(_php_error_log_ex((int) erropt, message, message_len, opt, headers) == SUCCESS); } /* }}} */ @@ -2322,11 +2318,7 @@ PHP_FUNCTION(is_uploaded_file) RETURN_FALSE; } - if (zend_hash_exists(SG(rfc1867_uploaded_files), path)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_hash_exists(SG(rfc1867_uploaded_files), path)); } /* }}} */ From b6cc5445447579b869bdf7c57078fe9d64233136 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 14:09:22 +0000 Subject: [PATCH 5/9] ext/standard/basic_functions.c: return bool instead of int for ignore_user_abort() The INI setting is stored and displayed as a bool already. --- ext/standard/basic_functions.c | 6 +++--- ext/standard/basic_functions.stub.php | 2 +- ext/standard/basic_functions_arginfo.h | 4 ++-- ext/standard/tests/general_functions/bug72300.phpt | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 07ec0d8242ae6..aa7d8412c7dd9 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2106,14 +2106,14 @@ PHP_FUNCTION(ignore_user_abort) { bool arg = 0; bool arg_is_null = 1; - int old_setting; + bool old_setting; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL Z_PARAM_BOOL_OR_NULL(arg, arg_is_null) ZEND_PARSE_PARAMETERS_END(); - old_setting = (unsigned short)PG(ignore_user_abort); + old_setting = PG(ignore_user_abort); if (!arg_is_null) { zend_string *key = ZSTR_INIT_LITERAL("ignore_user_abort", 0); @@ -2121,7 +2121,7 @@ PHP_FUNCTION(ignore_user_abort) zend_string_release_ex(key, 0); } - RETURN_LONG(old_setting); + RETURN_BOOL(old_setting); } /* }}} */ diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index a4e235fd37409..575979d70bbe3 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -2020,7 +2020,7 @@ function connection_aborted(): int {} function connection_status(): int {} -function ignore_user_abort(?bool $enable = null): int {} +function ignore_user_abort(?bool $enable = null): bool {} #ifdef HAVE_GETSERVBYNAME function getservbyname(string $service, string $protocol): int|false {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 437ecf8ccd634..2e1dd85c1dfa4 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f578c888fc5302f209e150bad1f1ce6e4107465b */ + * Stub hash: 8161b33b701550d81c763d86f1500267bec60c5b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -537,7 +537,7 @@ ZEND_END_ARG_INFO() #define arginfo_connection_status arginfo_ob_get_level -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ignore_user_abort, 0, 0, IS_LONG, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ignore_user_abort, 0, 0, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, enable, _IS_BOOL, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/standard/tests/general_functions/bug72300.phpt b/ext/standard/tests/general_functions/bug72300.phpt index 94d1f20f8ad89..4b82986e134d1 100644 --- a/ext/standard/tests/general_functions/bug72300.phpt +++ b/ext/standard/tests/general_functions/bug72300.phpt @@ -14,9 +14,9 @@ var_dump(ini_get("ignore_user_abort")); ?> --EXPECT-- -int(0) -int(1) +bool(false) +bool(true) string(1) "1" -int(1) -int(0) +bool(true) +bool(false) string(1) "0" From 9a14c25784396ad58c2d983dd677bcebb18d536e Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 14:11:06 +0000 Subject: [PATCH 6/9] ext/standard/basic_functions.c: return bool instead of int for connection_aborted() --- ext/standard/basic_functions.c | 2 +- ext/standard/basic_functions.stub.php | 2 +- ext/standard/basic_functions_arginfo.h | 4 ++-- ext/standard/tests/general_functions/connection_aborted.phpt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index aa7d8412c7dd9..eee49c8c81faa 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2088,7 +2088,7 @@ PHP_FUNCTION(connection_aborted) { ZEND_PARSE_PARAMETERS_NONE(); - RETURN_LONG(PG(connection_status) & PHP_CONNECTION_ABORTED); + RETURN_BOOL(PG(connection_status) & PHP_CONNECTION_ABORTED); } /* }}} */ diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 575979d70bbe3..1c2e5507db1e0 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -2016,7 +2016,7 @@ function get_include_path(): string|false {} /** @refcount 1 */ function print_r(mixed $value, bool $return = false): string|true {} -function connection_aborted(): int {} +function connection_aborted(): bool {} function connection_status(): int {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 2e1dd85c1dfa4..d7590acfbb8a1 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8161b33b701550d81c763d86f1500267bec60c5b */ + * Stub hash: 14871e360fae7faeac48129f049cbf2d3ef34ca5 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -533,7 +533,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_print_r, 0, 1, MAY_BE_STRING|MAY ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, return, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() -#define arginfo_connection_aborted arginfo_ob_get_level +#define arginfo_connection_aborted arginfo_ob_flush #define arginfo_connection_status arginfo_ob_get_level diff --git a/ext/standard/tests/general_functions/connection_aborted.phpt b/ext/standard/tests/general_functions/connection_aborted.phpt index 5932095f0978d..d40f3cf83d5cf 100644 --- a/ext/standard/tests/general_functions/connection_aborted.phpt +++ b/ext/standard/tests/general_functions/connection_aborted.phpt @@ -1,5 +1,5 @@ --TEST-- -int connection_aborted ( void ); +Basic test for connection_aborted() --CREDITS-- marcosptf - - #phparty7 - @phpsp - novatec/2015 - sao paulo - br --FILE-- @@ -7,4 +7,4 @@ marcosptf - - #phparty7 - @phpsp - novatec/2015 - sao p var_dump(connection_aborted()); ?> --EXPECT-- -int(0) +bool(false) From 80e7246ed53ffb41de8a5d2db0193431b59ffd5a Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 14:15:31 +0000 Subject: [PATCH 7/9] ext/standard/basic_functions.c: register_tick_function() always returns true --- ext/standard/basic_functions.stub.php | 2 +- ext/standard/basic_functions_arginfo.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 1c2e5507db1e0..5d46b24712954 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -2040,7 +2040,7 @@ function getprotobyname(string $protocol): int|false {} function getprotobynumber(int $protocol): string|false {} #endif -function register_tick_function(callable $callback, mixed ...$args): bool {} +function register_tick_function(callable $callback, mixed ...$args): true {} function unregister_tick_function(callable $callback): void {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index d7590acfbb8a1..9f8897c2e6f11 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 14871e360fae7faeac48129f049cbf2d3ef34ca5 */ + * Stub hash: 9938a9fd71c396655530d0c6d664d8b48ae1171b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -567,7 +567,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_getprotobynumber, 0, 1, MAY_BE_S ZEND_END_ARG_INFO() #endif -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_register_tick_function, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_register_tick_function, 0, 1, IS_TRUE, 0) ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) ZEND_END_ARG_INFO() From 0528a1d73f2f1d509161169a3f5c30a7c8c9f226 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 14:43:49 +0000 Subject: [PATCH 8/9] ext/standard/basic_functions.c: handle time_nanosleep() inputs ahead of time --- ext/standard/basic_functions.c | 8 +++---- .../tests/misc/time_nanosleep_error4.phpt | 14 ++++++------ .../tests/misc/time_nanosleep_error5.phpt | 14 ++++++------ ext/standard/tests/time/bug60222.phpt | 22 +++++++++---------- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index eee49c8c81faa..514fbc1e93ed9 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1158,8 +1158,8 @@ PHP_FUNCTION(time_nanosleep) zend_argument_value_error(1, "must be greater than or equal to 0"); RETURN_THROWS(); } - if (tv_nsec < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (tv_nsec < 0 || tv_nsec > 999999999) { + zend_argument_value_error(2, "must be between 0 and 999999999"); RETURN_THROWS(); } @@ -1173,10 +1173,8 @@ PHP_FUNCTION(time_nanosleep) add_assoc_long_ex(return_value, "seconds", sizeof("seconds")-1, php_rem.tv_sec); add_assoc_long_ex(return_value, "nanoseconds", sizeof("nanoseconds")-1, php_rem.tv_nsec); return; - } else if (errno == EINVAL) { - zend_value_error("Nanoseconds was not in the range 0 to 999 999 999 or seconds was negative"); - RETURN_THROWS(); } + ZEND_ASSERT(errno != EINVAL); RETURN_FALSE; } diff --git a/ext/standard/tests/misc/time_nanosleep_error4.phpt b/ext/standard/tests/misc/time_nanosleep_error4.phpt index 740a68b8344b0..12bf4e32c01a9 100644 --- a/ext/standard/tests/misc/time_nanosleep_error4.phpt +++ b/ext/standard/tests/misc/time_nanosleep_error4.phpt @@ -10,12 +10,12 @@ if (!function_exists('time_nanosleep')) die("skip"); --FILE-- getMessage(), "\n"; +} ?> ---EXPECTF-- -Fatal error: Uncaught ValueError: time_nanosleep(): Argument #2 ($nanoseconds) must be greater than or equal to 0 in %s:%d -Stack trace: -#0 %s(%d): time_nanosleep(0, -10) -#1 {main} - thrown in %s on line %d +--EXPECT-- +time_nanosleep(): Argument #2 ($nanoseconds) must be between 0 and 999999999 diff --git a/ext/standard/tests/misc/time_nanosleep_error5.phpt b/ext/standard/tests/misc/time_nanosleep_error5.phpt index 7116da5519ca0..2c374388a6324 100644 --- a/ext/standard/tests/misc/time_nanosleep_error5.phpt +++ b/ext/standard/tests/misc/time_nanosleep_error5.phpt @@ -7,12 +7,12 @@ time_nanosleep — Delay for a number of seconds and nanoseconds --FILE-- getMessage(), "\n"; +} ?> ---EXPECTF-- -Fatal error: Uncaught ValueError: Nanoseconds was not in the range 0 to 999 999 999 or seconds was negative in %s:%d -Stack trace: -#0 %s(%d): time_nanosleep(0, 1000000000) -#1 {main} - thrown in %s on line %d +--EXPECT-- +time_nanosleep(): Argument #2 ($nanoseconds) must be between 0 and 999999999 diff --git a/ext/standard/tests/time/bug60222.phpt b/ext/standard/tests/time/bug60222.phpt index 0256e2de1d5c2..1b607758cf032 100644 --- a/ext/standard/tests/time/bug60222.phpt +++ b/ext/standard/tests/time/bug60222.phpt @@ -2,18 +2,18 @@ Bug #60222 (time_nanosleep() does validate input params) --FILE-- getMessage() . "\n"; - } +try { + time_nanosleep(-1, 0); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} - try { - time_nanosleep(0, -1); - } catch (ValueError $exception) { - echo $exception->getMessage() . "\n"; - } +try { + time_nanosleep(0, -1); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} ?> --EXPECT-- time_nanosleep(): Argument #1 ($seconds) must be greater than or equal to 0 -time_nanosleep(): Argument #2 ($nanoseconds) must be greater than or equal to 0 +time_nanosleep(): Argument #2 ($nanoseconds) must be between 0 and 999999999 From 973c0a78016f067c80cb7b1e43c89aef56359abb Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sat, 29 Nov 2025 14:46:25 +0000 Subject: [PATCH 9/9] ext/standard/basic_functions.c: perform basic input checks for ip2long() --- ext/standard/basic_functions.c | 9 +++++++-- ext/standard/tests/network/ip.phpt | 6 ++---- .../tests/network/ip2long_errors.phpt | 20 +++++++++++++++++++ ext/standard/tests/network/ip_x86_64.phpt | 7 ++----- 4 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 ext/standard/tests/network/ip2long_errors.phpt diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 514fbc1e93ed9..5e03da9592f14 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -593,10 +593,15 @@ PHP_FUNCTION(ip2long) struct in_addr ip; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(addr, addr_len) + Z_PARAM_PATH(addr, addr_len) ZEND_PARSE_PARAMETERS_END(); - if (addr_len == 0 || inet_pton(AF_INET, addr, &ip) != 1) { + if (addr_len == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + + if (inet_pton(AF_INET, addr, &ip) != 1) { RETURN_FALSE; } RETURN_LONG(ntohl(ip.s_addr)); diff --git a/ext/standard/tests/network/ip.phpt b/ext/standard/tests/network/ip.phpt index b6ac49d5df6af..6924befea3b0b 100644 --- a/ext/standard/tests/network/ip.phpt +++ b/ext/standard/tests/network/ip.phpt @@ -7,21 +7,20 @@ if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); --FILE-- getMessage(), PHP_EOL; +} +try { + var_dump(ip2long("127\00.0.1")); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +ValueError: ip2long(): Argument #1 ($ip) must not be empty +ValueError: ip2long(): Argument #1 ($ip) must not contain any null bytes + diff --git a/ext/standard/tests/network/ip_x86_64.phpt b/ext/standard/tests/network/ip_x86_64.phpt index 16e855188aafa..58df8086577d3 100644 --- a/ext/standard/tests/network/ip_x86_64.phpt +++ b/ext/standard/tests/network/ip_x86_64.phpt @@ -7,21 +7,19 @@ if (PHP_INT_SIZE == 4) die("skip this test is for >32bit platform only"); --FILE--