From a8bdfa665b7a2d0027eed7954f0a0599d7d432e4 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 5 Feb 2026 21:23:42 +0000 Subject: [PATCH 01/18] ext/session: remove mod_user_class_name global --- ext/session/php_session.h | 1 - ext/session/session.c | 37 +++++-------------- .../tests/user_session_module/gh7787.phpt | 4 +- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 9bf97cca02bf3..ace8c6998cd5b 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -174,7 +174,6 @@ typedef struct _php_ps_globals { zval ps_validate_sid; zval ps_update_timestamp; } mod_user_names; - zend_string *mod_user_class_name; bool mod_user_implemented; bool mod_user_is_open; bool auto_start; diff --git a/ext/session/session.c b/ext/session/session.c index 7578a038eadd0..1bb2f3a80b69a 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -177,11 +177,6 @@ static void php_rshutdown_session_globals(void) PS(session_vars) = NULL; } - if (PS(mod_user_class_name)) { - zend_string_release(PS(mod_user_class_name)); - PS(mod_user_class_name) = NULL; - } - php_session_cleanup_filename(); /* User save handlers may end up directly here by misuse, bugs in user script, etc. */ @@ -516,9 +511,7 @@ static void php_session_save_current_state(bool write) if (write) { IF_SESSION_VARS() { - zend_string *handler_class_name = PS(mod_user_class_name); - const char *handler_function_name = "write"; - + zval *handler_function = &PS(mod_user_names).ps_write; if (PS(mod_data) || PS(mod_user_implemented)) { zend_string *val; @@ -530,7 +523,7 @@ static void php_session_save_current_state(bool write) && zend_string_equals(val, PS(session_vars)) ) { ret = PS(mod)->s_update_timestamp(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); - handler_function_name = handler_class_name != NULL ? "updateTimestamp" : "update_timestamp"; + handler_function = &PS(mod_user_names).ps_update_timestamp; } else { ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); } @@ -547,14 +540,12 @@ static void php_session_save_current_state(bool write) "is correct (%s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); - } else if (handler_class_name != NULL) { - php_error_docref(NULL, E_WARNING, "Failed to write session data using user " - "defined save handler. (session.save_path: %s, handler: %s::%s)", ZSTR_VAL(PS(save_path)), - ZSTR_VAL(handler_class_name), handler_function_name); } else { + zend_string *callable_name = zend_get_callable_name(handler_function); php_error_docref(NULL, E_WARNING, "Failed to write session data using user " "defined save handler. (session.save_path: %s, handler: %s)", ZSTR_VAL(PS(save_path)), - handler_function_name); + ZSTR_VAL(callable_name)); + zend_string_release_ex(callable_name, false); } } } @@ -2115,11 +2106,6 @@ PHP_FUNCTION(session_set_save_handler) RETURN_FALSE; } - if (PS(mod_user_class_name)) { - zend_string_release(PS(mod_user_class_name)); - } - PS(mod_user_class_name) = zend_string_copy(Z_OBJCE_P(obj)->name); - /* Define mandatory handlers */ SESSION_SET_USER_HANDLER_OO_MANDATORY(ps_open, "open"); SESSION_SET_USER_HANDLER_OO_MANDATORY(ps_close, "close"); @@ -2154,7 +2140,8 @@ PHP_FUNCTION(session_set_save_handler) /* Validate ID handler */ SESSION_SET_USER_HANDLER_OO(ps_validate_sid, zend_string_copy(validate_sid_name)); /* Update Timestamp handler */ - SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, zend_string_copy(update_timestamp_name)); + /* We need to provide a new string with the correct casing so that error messages work */ + SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, ZSTR_INIT_LITERAL("updateTimestamp", false)); } else { /* For BC reasons we accept methods even if the class does not implement the interface */ if (zend_hash_find_ptr(object_methods, validate_sid_name)) { @@ -2163,7 +2150,8 @@ PHP_FUNCTION(session_set_save_handler) } if (zend_hash_find_ptr(object_methods, update_timestamp_name)) { /* For BC reasons we accept methods even if the class does not implement the interface */ - SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, zend_string_copy(update_timestamp_name)); + /* We need to provide a new string with the correct casing so that error messages work */ + SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, ZSTR_INIT_LITERAL("updateTimestamp", false)); } } zend_string_release_ex(validate_sid_name, false); @@ -2240,12 +2228,6 @@ PHP_FUNCTION(session_set_save_handler) RETURN_FALSE; } - /* If a custom session handler is already set, release relevant info */ - if (PS(mod_user_class_name)) { - zend_string_release(PS(mod_user_class_name)); - PS(mod_user_class_name) = NULL; - } - /* remove shutdown function */ remove_user_shutdown_function("session_shutdown", strlen("session_shutdown")); @@ -2906,7 +2888,6 @@ static PHP_GINIT_FUNCTION(ps) ps_globals->session_status = php_session_none; ps_globals->default_mod = NULL; ps_globals->mod_user_implemented = false; - ps_globals->mod_user_class_name = NULL; ps_globals->mod_user_is_open = false; ps_globals->session_vars = NULL; ps_globals->set_handler = false; diff --git a/ext/session/tests/user_session_module/gh7787.phpt b/ext/session/tests/user_session_module/gh7787.phpt index 85ce7bd887cb6..ee62e8f049635 100644 --- a/ext/session/tests/user_session_module/gh7787.phpt +++ b/ext/session/tests/user_session_module/gh7787.phpt @@ -84,6 +84,6 @@ Warning: session_write_close(): Failed to write session data using user defined Deprecated: session_set_save_handler(): Providing individual callbacks instead of an object implementing SessionHandlerInterface is deprecated in %s on line %d -Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: %S, handler: write) in %s on line %d +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: %S, handler: {closure:%s:57}) in %s on line %d -Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: %S, handler: update_timestamp) in %s on line %d +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: %S, handler: {closure:%s:62}) in %s on line %d From a9496bdc2234a678beed678cb8c6a1780e4a54f9 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 6 Feb 2026 13:13:44 +0000 Subject: [PATCH 02/18] ext/session: refactor session_abort() By making the underlying function return a bool and not do duplicate checks --- ext/session/session.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index 1bb2f3a80b69a..aa155414b9187 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -101,7 +101,7 @@ zend_class_entry *php_session_update_timestamp_iface_entry; #define APPLY_TRANS_SID (PS(use_trans_sid) && !PS(use_only_cookies)) static zend_result php_session_send_cookie(void); -static zend_result php_session_abort(void); +static bool php_session_abort(void); static void proposed_session_id_to_session_id(const zval *proposed_session_id); /* Initialized in MINIT, readonly otherwise. */ @@ -1735,16 +1735,16 @@ PHPAPI php_session_status php_get_session_status(void) return PS(session_status); } -static zend_result php_session_abort(void) +static bool php_session_abort(void) { if (PS(session_status) == php_session_active) { if (PS(mod_data) || PS(mod_user_implemented)) { PS(mod)->s_close(&PS(mod_data)); } PS(session_status) = php_session_none; - return SUCCESS; + return true; } - return FAILURE; + return false; } static zend_result php_session_reset(void) @@ -2738,11 +2738,7 @@ PHP_FUNCTION(session_abort) RETURN_THROWS(); } - if (PS(session_status) != php_session_active) { - RETURN_FALSE; - } - php_session_abort(); - RETURN_TRUE; + RETURN_BOOL(php_session_abort()); } /* Reset session data from saved session data */ From 8926dc0140ea7a46901aa7dae6b54b47c59cc7ea Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 6 Feb 2026 13:14:32 +0000 Subject: [PATCH 03/18] ext/session: refactor session_reset() By making the underlying function return a bool and not do duplicate checks --- ext/session/session.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index aa155414b9187..260e553377132 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1747,13 +1747,13 @@ static bool php_session_abort(void) return false; } -static zend_result php_session_reset(void) +static bool php_session_reset(void) { if (PS(session_status) == php_session_active && php_session_initialize() == SUCCESS) { - return SUCCESS; + return true; } - return FAILURE; + return false; } @@ -2748,11 +2748,7 @@ PHP_FUNCTION(session_reset) RETURN_THROWS(); } - if (PS(session_status) != php_session_active) { - RETURN_FALSE; - } - php_session_reset(); - RETURN_TRUE; + RETURN_BOOL(php_session_reset()); } PHP_FUNCTION(session_status) From a0de1ace41196ca6a6da6c5c0bb51ca83caa50c4 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 6 Feb 2026 13:17:38 +0000 Subject: [PATCH 04/18] ext/session: refactor session_write_close() By making the underlying function return a bool and not do duplicate checks --- UPGRADING.INTERNALS | 3 +++ ext/session/php_session.h | 2 +- ext/session/session.c | 12 ++++-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 27414f52b3754..60615cb67ba60 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -97,6 +97,9 @@ PHP 8.6 INTERNALS UPGRADE NOTES . Dropped session_options parameter from all methods in mysqlnd_auth. The same information is present in conn->options and should be used instead. +- ext/session: + . php_session_flush() now returns a bool rather than a zend_result. + - ext/standard: . _php_error_log() now has a formal return type of zend_result. . _php_error_log() now accepts zend_string* values instead of char*. diff --git a/ext/session/php_session.h b/ext/session/php_session.h index ace8c6998cd5b..bf6fcbdcf49d1 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -263,7 +263,7 @@ PHPAPI zend_result php_session_register_serializer(const char *name, zend_result (*decode)(PS_SERIALIZER_DECODE_ARGS)); PHPAPI zend_result php_session_start(void); -PHPAPI zend_result php_session_flush(bool write); +PHPAPI bool php_session_flush(bool write); PHPAPI php_session_status php_get_session_status(void); PHPAPI const ps_module *_php_find_ps_module(const char *name); diff --git a/ext/session/session.c b/ext/session/session.c index 260e553377132..92ed91fbf86f7 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1720,14 +1720,14 @@ PHPAPI zend_result php_session_start(void) return SUCCESS; } -PHPAPI zend_result php_session_flush(bool write) +PHPAPI bool php_session_flush(bool write) { if (PS(session_status) == php_session_active) { php_session_save_current_state(write); PS(session_status) = php_session_none; - return SUCCESS; + return true; } - return FAILURE; + return false; } PHPAPI php_session_status php_get_session_status(void) @@ -2724,11 +2724,7 @@ PHP_FUNCTION(session_write_close) RETURN_THROWS(); } - if (PS(session_status) != php_session_active) { - RETURN_FALSE; - } - php_session_flush(true); - RETURN_TRUE; + RETURN_BOOL(php_session_flush(true)); } /* Abort session and end session. Session data will not be written */ From 1041a47ed3822f39c34562b9fa6bb79e122f3072 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 6 Feb 2026 16:11:36 +0000 Subject: [PATCH 05/18] ext/standard: throw ValueError if argument contains null byte in session_module_name() And fix error message to use 'must not' rather than 'cannot' --- UPGRADING | 4 ++++ ext/session/session.c | 7 +++--- ext/session/tests/bug73100.phpt | 2 +- .../tests/session_module_name_errors.phpt | 22 +++++++++++++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 ext/session/tests/session_module_name_errors.phpt diff --git a/UPGRADING b/UPGRADING index 8a1c61b9192cc..b1db9893de628 100644 --- a/UPGRADING +++ b/UPGRADING @@ -23,6 +23,10 @@ PHP 8.6 UPGRADE NOTES . Invalid values now throw in Phar::mungServer() instead of being silently ignored. +- Session: + . A ValueError is not thrown if $name is a string containing null bytes in + session_module_name(). + - Standard: . Invalid mode values now throw in array_filter() instead of being silently defaulted to 0. diff --git a/ext/session/session.c b/ext/session/session.c index 92ed91fbf86f7..e3e17a37fbf1d 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1996,9 +1996,8 @@ PHP_FUNCTION(session_name) PHP_FUNCTION(session_module_name) { zend_string *name = NULL; - zend_string *ini_name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &name) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!", &name) == FAILURE) { RETURN_THROWS(); } @@ -2015,7 +2014,7 @@ PHP_FUNCTION(session_module_name) if (name) { if (zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_USER))) { - zend_argument_value_error(1, "cannot be \"user\""); + zend_argument_value_error(1, "must not be \"user\""); RETURN_THROWS(); } if (!_php_find_ps_module(ZSTR_VAL(name))) { @@ -2029,7 +2028,7 @@ PHP_FUNCTION(session_module_name) } PS(mod_data) = NULL; - ini_name = ZSTR_INIT_LITERAL("session.save_handler", false); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.save_handler", false); zend_alter_ini_entry(ini_name, name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); zend_string_release_ex(ini_name, false); } diff --git a/ext/session/tests/bug73100.phpt b/ext/session/tests/bug73100.phpt index 21e698a14aba8..fc9984428726f 100644 --- a/ext/session/tests/bug73100.phpt +++ b/ext/session/tests/bug73100.phpt @@ -24,5 +24,5 @@ bool(true) Warning: session_module_name(): Session save handler module cannot be changed when a session is active (started from %s on line %d) in %s on line %d bool(true) -session_module_name(): Argument #1 ($module) cannot be "user" +session_module_name(): Argument #1 ($module) must not be "user" ===DONE=== diff --git a/ext/session/tests/session_module_name_errors.phpt b/ext/session/tests/session_module_name_errors.phpt new file mode 100644 index 0000000000000..f00171e6584ab --- /dev/null +++ b/ext/session/tests/session_module_name_errors.phpt @@ -0,0 +1,22 @@ +--TEST-- +session_module_name(): errors +--EXTENSIONS-- +session +--FILE-- +getMessage(), PHP_EOL; +} +try { + var_dump(session_module_name("fi\0le")); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: session_module_name(): Argument #1 ($module) must not be "user" +ValueError: session_module_name(): Argument #1 ($module) must not contain any null bytes From f6088f574c9cf20a9b5f5810b1d75d8146d03122 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 6 Feb 2026 17:29:20 +0000 Subject: [PATCH 06/18] ext/session: remove session_adapt_url() function This is unused and only exist for the deprecated (and dangerous) GET/POST session ID feature --- UPGRADING.INTERNALS | 1 + ext/session/php_session.h | 2 -- ext/session/session.c | 11 ----------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 60615cb67ba60..062e704fb7a08 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -99,6 +99,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES - ext/session: . php_session_flush() now returns a bool rather than a zend_result. + . Removed session_adapt_url(). - ext/standard: . _php_error_log() now has a formal return type of zend_result. diff --git a/ext/session/php_session.h b/ext/session/php_session.h index bf6fcbdcf49d1..3b7acf151997e 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -248,8 +248,6 @@ PHPAPI zend_string *php_session_create_id(PS_CREATE_SID_ARGS); PHPAPI zend_result php_session_validate_sid(PS_VALIDATE_SID_ARGS); PHPAPI zend_result php_session_update_timestamp(PS_UPDATE_TIMESTAMP_ARGS); -PHPAPI void session_adapt_url(const char *url, size_t url_len, char **new_url, size_t *new_len); - PHPAPI zend_result php_session_destroy(void); PHPAPI void php_add_session_var(zend_string *name); PHPAPI zval *php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash); diff --git a/ext/session/session.c b/ext/session/session.c index e3e17a37fbf1d..550b2bd412945 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1756,17 +1756,6 @@ static bool php_session_reset(void) return false; } - -/* This API is not used by any PHP modules including session currently. - session_adapt_url() may be used to set Session ID to target url without - starting "URL-Rewriter" output handler. */ -PHPAPI void session_adapt_url(const char *url, size_t url_len, char **new_url, size_t *new_len) -{ - if (APPLY_TRANS_SID && (PS(session_status) == php_session_active)) { - *new_url = php_url_scanner_adapt_single_url(url, url_len, ZSTR_VAL(PS(session_name)), ZSTR_VAL(PS(id)), new_len, true); - } -} - /* ******************************** * Userspace exported functions * ******************************** */ From ba17532fed3ffd54dedde323d3018726ebeae491 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 6 Feb 2026 17:36:40 +0000 Subject: [PATCH 07/18] ext/session: use known 1 char zend_string to update boolean INI setting --- ext/session/session.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index 550b2bd412945..1630c76cf4014 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1896,7 +1896,7 @@ PHP_FUNCTION(session_set_cookie_params) } if (!secure_null) { ini_name = ZSTR_INIT_LITERAL("session.cookie_secure", false); - result = zend_alter_ini_entry_chars(ini_name, secure ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + result = zend_alter_ini_entry(ini_name, secure ? ZSTR_CHAR('1') : ZSTR_CHAR('0'), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; @@ -1905,7 +1905,7 @@ PHP_FUNCTION(session_set_cookie_params) } if (!partitioned_null) { ini_name = ZSTR_INIT_LITERAL("session.cookie_partitioned", false); - result = zend_alter_ini_entry_chars(ini_name, partitioned ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + result = zend_alter_ini_entry(ini_name, partitioned ? ZSTR_CHAR('1') : ZSTR_CHAR('0'), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; @@ -1914,7 +1914,7 @@ PHP_FUNCTION(session_set_cookie_params) } if (!httponly_null) { ini_name = ZSTR_INIT_LITERAL("session.cookie_httponly", false); - result = zend_alter_ini_entry_chars(ini_name, httponly ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + result = zend_alter_ini_entry(ini_name, httponly ? ZSTR_CHAR('1') : ZSTR_CHAR('0'), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; From 71096cd87382c3df399a349a1ffd36f112b37aea Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Fri, 6 Feb 2026 17:51:48 +0000 Subject: [PATCH 08/18] ext/session: use zend_strings for open handler --- UPGRADING.INTERNALS | 4 ++++ ext/session/mod_files.c | 17 ++++++++++------- ext/session/mod_user.c | 7 +++---- ext/session/mod_user_class.c | 5 ++--- ext/session/php_session.h | 2 +- ext/session/session.c | 4 ++-- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 062e704fb7a08..1d8734d9fb076 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -100,6 +100,10 @@ PHP 8.6 INTERNALS UPGRADE NOTES - ext/session: . php_session_flush() now returns a bool rather than a zend_result. . Removed session_adapt_url(). + . PS_OPEN_ARGS is now defined as + `void **mod_data, zend_string *save_path, zend_string *session_name` + rather than + `void **mod_data, const char *save_path, const char *session_name` - ext/standard: . _php_error_log() now has a formal return type of zend_result. diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 869bb1052c6df..87bcb7e3690fc 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -369,19 +369,22 @@ PS_OPEN_FUNC(files) int argc = 0; size_t dirdepth = 0; int filemode = 0600; + const char *used_save_path; - if (*save_path == '\0') { + if (ZSTR_LEN(save_path) == 0) { /* if save path is an empty string, determine the temporary dir */ - save_path = php_get_temporary_directory(); + used_save_path = php_get_temporary_directory(); - if (php_check_open_basedir(save_path)) { + if (php_check_open_basedir(used_save_path)) { return FAILURE; } + } else { + used_save_path = ZSTR_VAL(save_path); } /* split up input parameter */ - last = save_path; - p = strchr(save_path, ';'); + last = used_save_path; + p = strchr(used_save_path, ';'); while (p) { argv[argc++] = last; last = ++p; @@ -407,14 +410,14 @@ PS_OPEN_FUNC(files) return FAILURE; } } - save_path = argv[argc - 1]; + used_save_path = argv[argc - 1]; data = ecalloc(1, sizeof(*data)); data->fd = -1; data->dirdepth = dirdepth; data->filemode = filemode; - data->basedir = zend_string_init(save_path, strlen(save_path), /* persistent */ false); + data->basedir = zend_string_init(used_save_path, strlen(used_save_path), /* persistent */ false); if (PS_GET_MOD_DATA()) { ps_close_files(mod_data); diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c index 5783ca625a4a6..90b91926a62c3 100644 --- a/ext/session/mod_user.c +++ b/ext/session/mod_user.c @@ -83,12 +83,11 @@ PS_OPEN_FUNC(user) { zval args[2]; zval retval; - zend_result ret = FAILURE; ZEND_ASSERT(!Z_ISUNDEF(PSF(open))); - ZVAL_STRING(&args[0], (char*)save_path); - ZVAL_STRING(&args[1], (char*)session_name); + ZVAL_STR(&args[0], zend_string_dup(save_path, false)); + ZVAL_STR(&args[1], zend_string_dup(session_name, false)); zend_try { ps_call_handler(&PSF(open), 2, args, &retval); @@ -102,7 +101,7 @@ PS_OPEN_FUNC(user) PS(mod_user_implemented) = true; - ret = verify_bool_return_type_userland_calls(&retval); + zend_result ret = verify_bool_return_type_userland_calls(&retval); zval_ptr_dtor(&retval); return ret; } diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c index 1735423e902c4..618cc6bd67965 100644 --- a/ext/session/mod_user_class.c +++ b/ext/session/mod_user_class.c @@ -36,11 +36,10 @@ PHP_METHOD(SessionHandler, open) { - char *save_path = NULL, *session_name = NULL; - size_t save_path_len, session_name_len; + zend_string *save_path, *session_name; zend_result ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &save_path, &save_path_len, &session_name, &session_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &save_path, &session_name) == FAILURE) { RETURN_THROWS(); } diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 3b7acf151997e..8c857d29a5fc0 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -26,7 +26,7 @@ #define PHP_SESSION_VERSION PHP_VERSION /* save handler macros */ -#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name +#define PS_OPEN_ARGS void **mod_data, zend_string *save_path, zend_string *session_name #define PS_CLOSE_ARGS void **mod_data #define PS_READ_ARGS void **mod_data, zend_string *key, zend_string **val, zend_long maxlifetime #define PS_WRITE_ARGS void **mod_data, zend_string *key, zend_string *val, zend_long maxlifetime diff --git a/ext/session/session.c b/ext/session/session.c index 1630c76cf4014..da4e57ff9a1d3 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -424,7 +424,7 @@ static zend_result php_session_initialize(void) } /* Open session handler first */ - if (PS(mod)->s_open(&PS(mod_data), ZSTR_VAL(PS(save_path)), ZSTR_VAL(PS(session_name))) == FAILURE + if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)) == FAILURE /* || PS(mod_data) == NULL */ /* FIXME: open must set valid PS(mod_data) with success */ ) { php_session_abort(); @@ -2351,7 +2351,7 @@ PHP_FUNCTION(session_regenerate_id) zend_string_release_ex(PS(id), false); PS(id) = NULL; - if (PS(mod)->s_open(&PS(mod_data), ZSTR_VAL(PS(save_path)), ZSTR_VAL(PS(session_name))) == FAILURE) { + if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)) == FAILURE) { PS(session_status) = php_session_none; if (!EG(exception)) { zend_throw_error(NULL, "Failed to open session: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); From 888b393d2fa4aec53a97308fc6ffcae7810e0ea5 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 9 Feb 2026 11:04:24 +0000 Subject: [PATCH 09/18] ext/session: fix typo in comment --- ext/session/session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/session/session.c b/ext/session/session.c index da4e57ff9a1d3..4b49f14b29b28 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1682,7 +1682,7 @@ PHPAPI zend_result php_session_start(void) * Cookies are preferred, because initially cookie and get * variables will be available. * URL/POST session ID may be used when use_only_cookies=Off. - * session.use_strice_mode=On prevents session adoption. + * session.use_strict_mode=On prevents session adoption. * Session based file upload progress uses non-cookie ID. */ From 9026396c2672d853c8aadd338bd07592568d12d8 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 9 Feb 2026 11:05:51 +0000 Subject: [PATCH 10/18] ext/session: simplify php_session_reset() --- ext/session/session.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index 4b49f14b29b28..e6412bbc0d81c 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1749,11 +1749,7 @@ static bool php_session_abort(void) static bool php_session_reset(void) { - if (PS(session_status) == php_session_active - && php_session_initialize() == SUCCESS) { - return true; - } - return false; + return PS(session_status) == php_session_active && php_session_initialize() == SUCCESS; } /* ******************************** From ca08e5f7fe4df1199a251be289cd9f388459adaf Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 9 Feb 2026 11:12:51 +0000 Subject: [PATCH 11/18] ext/session: reduce scope of variables --- ext/session/session.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index e6412bbc0d81c..31c525c89e8c1 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -995,15 +995,12 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary) PS_SERIALIZER_DECODE_FUNC(php_binary) { - const char *p; const char *endptr = val + vallen; - zend_string *name; php_unserialize_data_t var_hash; - zval *current, rv; PHP_VAR_UNSERIALIZE_INIT(var_hash); - for (p = val; p < endptr; ) { + for (const char *p = val; p < endptr; ) { size_t namelen = ((unsigned char)(*p)) & (~PS_BIN_UNDEF); if (namelen > PS_BIN_MAX || (p + namelen) >= endptr) { @@ -1011,11 +1008,12 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) return FAILURE; } - name = zend_string_init(p + 1, namelen, false); + zend_string *name = zend_string_init(p + 1, namelen, false); p += namelen + 1; - current = var_tmp_var(&var_hash); + zval *current = var_tmp_var(&var_hash); if (php_var_unserialize(current, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash)) { + zval rv; ZVAL_PTR(&rv, current); php_set_session_var(name, &rv, &var_hash); } else { @@ -1300,8 +1298,6 @@ static const php_session_cache_limiter_t php_session_cache_limiters[] = { static int php_session_cache_limiter(void) { - const php_session_cache_limiter_t *lim; - if (ZSTR_LEN(PS(cache_limiter)) == 0) { return 0; } @@ -1313,7 +1309,7 @@ static int php_session_cache_limiter(void) return -2; } - for (lim = php_session_cache_limiters; lim->name; lim++) { + for (const php_session_cache_limiter_t *lim = php_session_cache_limiters; lim->name; lim++) { if (!strcasecmp(lim->name, ZSTR_VAL(PS(cache_limiter)))) { lim->func(); return 0; @@ -1446,9 +1442,8 @@ PHPAPI const ps_module *_php_find_ps_module(const char *name) PHPAPI const ps_serializer *_php_find_ps_serializer(const char *name) { const ps_serializer *found_serializer = NULL; - const ps_serializer *current_serializer; - for (current_serializer = ps_serializers; current_serializer->name; current_serializer++) { + for (const ps_serializer *current_serializer = ps_serializers; current_serializer->name; current_serializer++) { if (!strcasecmp(name, current_serializer->name)) { found_serializer = current_serializer; break; @@ -1643,16 +1638,14 @@ PHPAPI zend_result php_session_reset_id(void) PHPAPI zend_result php_session_start(void) { - const char *value; - switch (PS(session_status)) { case php_session_active: php_session_session_already_started_error(E_NOTICE, "Ignoring session_start() because a session has already been started"); return FAILURE; break; - case php_session_disabled: - value = zend_ini_string(ZEND_STRL("session.save_handler"), false); + case php_session_disabled: { + const char *value = zend_ini_string(ZEND_STRL("session.save_handler"), false); if (!PS(mod) && value) { PS(mod) = _php_find_ps_module(value); if (!PS(mod)) { @@ -1670,6 +1663,7 @@ PHPAPI zend_result php_session_start(void) } PS(session_status) = php_session_none; ZEND_FALLTHROUGH; + } case php_session_none: default: @@ -1793,9 +1787,6 @@ PHP_FUNCTION(session_set_cookie_params) } if (options_ht) { - zend_string *key; - zval *value; - if (path) { zend_argument_value_error(2, "must be null when argument #1 ($lifetime_or_options) is an array"); RETURN_THROWS(); @@ -1815,7 +1806,7 @@ PHP_FUNCTION(session_set_cookie_params) zend_argument_value_error(5, "must be null when argument #1 ($lifetime_or_options) is an array"); RETURN_THROWS(); } - ZEND_HASH_FOREACH_STR_KEY_VAL(options_ht, key, value) { + ZEND_HASH_FOREACH_STR_KEY_VAL(options_ht, zend_string *key, zval *value) { if (key) { ZVAL_DEREF(value); if (zend_string_equals_literal_ci(key, "lifetime")) { @@ -2461,7 +2452,6 @@ PHP_FUNCTION(session_create_id) PHP_FUNCTION(session_cache_limiter) { zend_string *limiter = NULL; - zend_string *ini_name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &limiter) == FAILURE) { RETURN_THROWS(); @@ -2480,7 +2470,7 @@ PHP_FUNCTION(session_cache_limiter) RETVAL_STRINGL(ZSTR_VAL(PS(cache_limiter)), ZSTR_LEN(PS(cache_limiter))); if (limiter) { - ini_name = ZSTR_INIT_LITERAL("session.cache_limiter", false); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.cache_limiter", false); zend_alter_ini_entry(ini_name, limiter, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); zend_string_release_ex(ini_name, false); } @@ -2566,8 +2556,6 @@ static zend_result php_session_start_set_ini(zend_string *varname, zend_string * PHP_FUNCTION(session_start) { zval *options = NULL; - zval *value; - zend_string *str_idx; bool read_and_close = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a", &options) == FAILURE) { @@ -2591,7 +2579,7 @@ PHP_FUNCTION(session_start) /* set options */ if (options) { - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), str_idx, value) { + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), zend_string *str_idx, zval *value) { if (UNEXPECTED(!str_idx)) { zend_argument_value_error(1, "must be of type array with keys as string"); RETURN_THROWS(); From cc304d14abff9c5f7ca28f48ff127705be5d1921 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 9 Feb 2026 11:16:33 +0000 Subject: [PATCH 12/18] ext/session: refactor bin_to_readable() --- ext/session/session.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index 31c525c89e8c1..cf9ea05fc3417 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -305,23 +305,17 @@ static zend_result php_session_decode(const zend_string *data) static const char hexconvtab[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-"; -static void bin_to_readable(unsigned char *in, size_t inlen, char *out, size_t outlen, char nbits) +static void bin_to_readable(const unsigned char *in, size_t inlen, char *out, size_t outlen, char nbits) { - unsigned char *p, *q; - unsigned short w; - int mask; - int have; - - p = (unsigned char *)in; - q = (unsigned char *)in + inlen; - - w = 0; - have = 0; - mask = (1 << nbits) - 1; + const unsigned char *p = in; + const unsigned char *end_p = in + inlen; + unsigned short w = 0; + int have = 0; + const int mask = (1 << nbits) - 1; while (outlen--) { if (have < nbits) { - if (p < q) { + if (p < end_p) { w |= *p++ << have; have += 8; } else { From 8af056206e42113d4a91d3ec92ccf5a089cf69b4 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 9 Feb 2026 11:21:12 +0000 Subject: [PATCH 13/18] ext/session: add const qualifiers --- ext/session/session.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index cf9ea05fc3417..6930ea8ca2d93 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1186,12 +1186,12 @@ typedef struct { #define ADD_HEADER(a) sapi_add_header(a, strlen(a), 1); #define MAX_STR 512 -static const char *month_names[] = { +static const char *const month_names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static const char *week_days[] = { +static const char *const week_days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; @@ -2535,7 +2535,7 @@ PHP_FUNCTION(session_decode) RETURN_BOOL(php_session_decode(str) == SUCCESS); } -static zend_result php_session_start_set_ini(zend_string *varname, zend_string *new_value) { +static zend_result php_session_start_set_ini(const zend_string *varname, zend_string *new_value) { zend_result ret; smart_str buf ={0}; smart_str_appends(&buf, "session"); From e1b2f1f5cb82a8a8bcfae5935451528a598478ee Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 9 Feb 2026 11:28:45 +0000 Subject: [PATCH 14/18] ext/session: move variable initialization out of if condition --- ext/session/session.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ext/session/session.c b/ext/session/session.c index 6930ea8ca2d93..d9a4e2b5a4d2b 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2978,14 +2978,12 @@ static PHP_MINFO_FUNCTION(session) static bool early_find_sid_in(zval *dest, int where) { - zval *potential_session_id; - if (Z_ISUNDEF(PG(http_globals)[where])) { return false; } - if ((potential_session_id = zend_hash_find(Z_ARRVAL(PG(http_globals)[where]), PS(session_name))) - && Z_TYPE_P(potential_session_id) == IS_STRING) { + zval *potential_session_id = zend_hash_find(Z_ARRVAL(PG(http_globals)[where]), PS(session_name)); + if (potential_session_id && Z_TYPE_P(potential_session_id) == IS_STRING) { zval_ptr_dtor(dest); ZVAL_COPY_DEREF(dest, potential_session_id); return true; @@ -3013,15 +3011,15 @@ static void php_session_rfc1867_early_find_sid(php_session_rfc1867_progress *pro static bool php_check_cancel_upload(const php_session_rfc1867_progress *progress) { - zval *progress_ary, *cancel_upload; - - if ((progress_ary = zend_symtable_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), progress->key.s)) == NULL) { + const zval *progress_ary = zend_symtable_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), progress->key.s); + if (progress_ary == NULL) { return false; } if (Z_TYPE_P(progress_ary) != IS_ARRAY) { return false; } - if ((cancel_upload = zend_hash_str_find(Z_ARRVAL_P(progress_ary), ZEND_STRL("cancel_upload"))) == NULL) { + const zval *cancel_upload = zend_hash_str_find(Z_ARRVAL_P(progress_ary), ZEND_STRL("cancel_upload")); + if (cancel_upload == NULL) { return false; } return Z_TYPE_P(cancel_upload) == IS_TRUE; From fcff846a73de03fe02fc2fca2e212cbc12feb945 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 9 Feb 2026 13:22:35 +0100 Subject: [PATCH 15/18] Fix borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization (GH-21121) Fixes OSS-Fuzz #481014628 Introduced in GH-20628 Co-authored-by: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com> --- Zend/Optimizer/block_pass.c | 4 +++- ext/opcache/tests/oss-fuzz-481014628.phpt | 27 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/oss-fuzz-481014628.phpt diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 7f97caa1fdab4..5a0af26303913 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -176,7 +176,9 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array && zend_optimizer_update_op1_const(op_array, opline, &c)) { VAR_SOURCE(op1) = NULL; if (opline->opcode != ZEND_JMP_NULL - && !zend_bitset_in(used_ext, VAR_NUM(src->result.var))) { + && !zend_bitset_in(used_ext, VAR_NUM(src->result.var)) + /* FETCH_W with ZEND_FETCH_GLOBAL_LOCK does not free op1, which will be used again. */ + && !(opline->opcode == ZEND_FETCH_W && (opline->extended_value & ZEND_FETCH_GLOBAL_LOCK))) { literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); } diff --git a/ext/opcache/tests/oss-fuzz-481014628.phpt b/ext/opcache/tests/oss-fuzz-481014628.phpt new file mode 100644 index 0000000000000..8aa6cf3fe1fdb --- /dev/null +++ b/ext/opcache/tests/oss-fuzz-481014628.phpt @@ -0,0 +1,27 @@ +--TEST-- +OSS-Fuzz #481014628: Borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--FILE-- + +--EXPECT-- +NULL +int(42) From 7c6f08945f89754f2800e0af1cc2181f639985fe Mon Sep 17 00:00:00 2001 From: Petr Sumbera Date: Tue, 16 Dec 2025 14:39:43 +0100 Subject: [PATCH 16/18] Improve shared_alloc_shm.c strategy to support OPcache JIT on Solaris The SysV shared memory allocator in OPcache hardcodes a maximum segment size of 32MB (SEG_ALLOC_SIZE_MAX). If the JIT buffer exceeds this, which it does with the default 64MB size, startup will fail with "Insufficient shared memory!". The allocator will now try allocating a contiguous buffer first, and only then use segmentation by searching for continuously smaller powers of 2. Fixes GH-20718 Closes GH-20719 --- NEWS | 4 ++++ ext/opcache/shared_alloc_shm.c | 43 +++++++++++++++++----------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index ab6d95471bd64..cda0658d87cfd 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,10 @@ PHP NEWS . Fixed bug GH-21097 (Accessing Dom\Node properties can can throw TypeError). (ndossche) +- Opcache: + . Fixed bug GH-20718 ("Insufficient shared memory" when using JIT on Solaris). + (Petr Sumbera) + - PDO_PGSQL: . Fixed bug GH-21055 (connection attribute status typo for GSS negotiation). (lsaos) diff --git a/ext/opcache/shared_alloc_shm.c b/ext/opcache/shared_alloc_shm.c index 09a357d189ed4..b9f8ca4524a05 100644 --- a/ext/opcache/shared_alloc_shm.c +++ b/ext/opcache/shared_alloc_shm.c @@ -42,7 +42,6 @@ # define MIN(x, y) ((x) > (y)? (y) : (x)) #endif -#define SEG_ALLOC_SIZE_MAX 32*1024*1024 #define SEG_ALLOC_SIZE_MIN 2*1024*1024 typedef struct { @@ -53,36 +52,38 @@ typedef struct { static int create_segments(size_t requested_size, zend_shared_segment_shm ***shared_segments_p, int *shared_segments_count, const char **error_in) { int i; - size_t allocate_size = 0, remaining_bytes = requested_size, seg_allocate_size; + size_t allocate_size = 0, remaining_bytes, seg_allocate_size; int first_segment_id = -1; key_t first_segment_key = -1; struct shmid_ds sds; int shmget_flags; zend_shared_segment_shm *shared_segments; - seg_allocate_size = SEG_ALLOC_SIZE_MAX; - /* determine segment size we _really_ need: - * no more than to include requested_size - */ - while (requested_size * 2 <= seg_allocate_size && seg_allocate_size > SEG_ALLOC_SIZE_MIN) { - seg_allocate_size >>= 1; - } - shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL; - /* try allocating this much, if not - try shrinking */ - while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) { - allocate_size = MIN(requested_size, seg_allocate_size); - first_segment_id = shmget(first_segment_key, allocate_size, shmget_flags); - if (first_segment_id != -1) { - break; + /* Try contiguous allocation first. */ + seg_allocate_size = requested_size; + first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags); + if (UNEXPECTED(first_segment_id == -1)) { + /* Search for biggest n^2 < requested_size. */ + seg_allocate_size = SEG_ALLOC_SIZE_MIN; + while (seg_allocate_size < requested_size / 2) { + seg_allocate_size *= 2; } - seg_allocate_size >>= 1; /* shrink the allocated block */ - } - if (first_segment_id == -1) { - *error_in = "shmget"; - return ALLOC_FAILURE; + /* try allocating this much, if not - try shrinking */ + while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) { + first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags); + if (first_segment_id != -1) { + break; + } + seg_allocate_size >>= 1; /* shrink the allocated block */ + } + + if (first_segment_id == -1) { + *error_in = "shmget"; + return ALLOC_FAILURE; + } } *shared_segments_count = ((requested_size - 1) / seg_allocate_size) + 1; From 29cd577aa65c1b950984d678e1ce0d8d834459c6 Mon Sep 17 00:00:00 2001 From: Jorg Adam Sowa Date: Mon, 9 Feb 2026 15:12:05 +0100 Subject: [PATCH 17/18] ci: Add fork protection to workflow verify-bundled-files (GH-21171) --- .github/workflows/verify-bundled-files.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index 6cce1a14cf7f3..291cd6adaa3da 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -16,6 +16,7 @@ permissions: jobs: VERIFY_BUNDLED_FILES: + if: github.repository == 'php/php-src' || github.event_name == 'workflow_dispatch' name: Verify Bundled Files runs-on: ubuntu-24.04 steps: From 95fb1747309c3cc3d78162377ebbf2b31e0e43dd Mon Sep 17 00:00:00 2001 From: Arshid Date: Mon, 9 Feb 2026 19:43:58 +0530 Subject: [PATCH 18/18] [skip ci] Remove dead code in Zend/zend_multiply.h after zend_error_noreturn() (GH-21153) --- Zend/zend_multiply.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h index 200bedd88cacf..716e3ba4b5715 100644 --- a/Zend/zend_multiply.h +++ b/Zend/zend_multiply.h @@ -342,7 +342,6 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t if (UNEXPECTED(overflow)) { zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset); - return 0; } return ret; } @@ -355,7 +354,6 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si if (UNEXPECTED(overflow)) { zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset); - return 0; } return ret; }