diff --git a/ext/session/session.c b/ext/session/session.c index ba71d709a536..8e393b08fe56 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2505,6 +2505,9 @@ PHP_FUNCTION(session_create_id) int limit = 3; while (limit--) { new_id = PS(mod)->s_create_sid(&PS(mod_data)); + if (!new_id) { + break; + } if (!PS(mod)->s_validate_sid || (PS(mod_user_implemented) && Z_ISUNDEF(PS(mod_user_names).ps_validate_sid))) { break; } else { @@ -2526,6 +2529,9 @@ PHP_FUNCTION(session_create_id) zend_string_release_ex(new_id, 0); } else { smart_str_free(&id); + if (EG(exception)) { + RETURN_THROWS(); + } php_error_docref(NULL, E_WARNING, "Failed to create new ID"); RETURN_FALSE; } diff --git a/ext/session/tests/user_session_module/session_create_id_create_sid_throws.phpt b/ext/session/tests/user_session_module/session_create_id_create_sid_throws.phpt new file mode 100644 index 000000000000..b65c0671d940 --- /dev/null +++ b/ext/session/tests/user_session_module/session_create_id_create_sid_throws.phpt @@ -0,0 +1,49 @@ +--TEST-- +session_create_id() when the create_sid handler throws +--INI-- +session.save_handler=files +session.name=PHPSESSID +session.gc_probability=0 +--EXTENSIONS-- +session +--FILE-- +calls++ > 0) { + throw new Exception('create_sid failed'); + } + return parent::create_sid(); + } + + public function validateId(string $id): bool + { + return false; + } +} + +session_set_save_handler(new MySessionHandler(), true); +session_start(); + +try { + session_create_id(); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo $previous::class, ": ", $previous->getMessage(), PHP_EOL; +} + +var_dump(session_status() === PHP_SESSION_ACTIVE); + +?> +--EXPECT-- +Error: Session id must be a string +Exception: create_sid failed +bool(true)