Commit 6da7eabab46 for php.net
commit 6da7eabab46d6324eda6702a03fa2a58e85f1519
Merge: 5467b514f00 28e41a9c475
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Wed Sep 23 12:22:24 2026 -0400
Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
ext/session: Preserve exceptions thrown by create_sid()
diff --cc NEWS
index b3d2e7ebd6e,a23aba2642b..785273bed94
--- a/NEWS
+++ b/NEWS
@@@ -91,11 -76,9 +91,13 @@@ PH
- Session:
. Fixed session_start() continuing after a failed create_sid() when
session.use_strict_mode rejects the supplied ID. (Ilia Alshanetsky)
+ . Fixed exceptions from user-defined create_sid() handlers being replaced
+ by return-value validation errors. (Ilia Alshanetsky)
+- SPL:
+ . Fixed bug GH-23385 (SplDoublyLinkedList::serialize() use-after-free when
+ __serialize() removes an element). (David Carlier)
+
- SQLite:
. Fixed a crash when SQLite3::close() is called from a userland callback.
(Ilia Alshanetsky)
diff --cc ext/session/mod_user.c
index 5c6fe557771,61db72b4cf1..174a0e4822e
--- a/ext/session/mod_user.c
+++ b/ext/session/mod_user.c
@@@ -232,15 -243,14 +232,17 @@@ PS_CREATE_SID_FUNC(user
return NULL;
}
- if (!id) {
+ if (UNEXPECTED(Z_TYPE(retval) != IS_STRING)) {
+ /* Will no longer be needed in PHP 9 as the interface return type will be in effect */
- zend_throw_error(zend_ce_type_error, "Session id must be of type string, %s given", zend_zval_type_name(&retval));
+ if (!EG(exception)) {
- zend_throw_error(NULL, "Session id must be a string");
++ zend_throw_error(zend_ce_type_error, "Session id must be of type string, %s given", zend_zval_type_name(&retval));
+ }
+ zval_ptr_dtor(&retval);
return NULL;
}
+ ZEND_ASSERT(Z_TYPE(retval) == IS_STRING);
- return id;
+ return Z_STR(retval);
}
/* function as defined by PS_MOD */
diff --cc ext/session/tests/user_session_module/session_create_sid_return_destructor_throws.phpt
index 00000000000,18bb97779e0..7c8c9b1fdc7
mode 000000,100644..100644
--- a/ext/session/tests/user_session_module/session_create_sid_return_destructor_throws.phpt
+++ b/ext/session/tests/user_session_module/session_create_sid_return_destructor_throws.phpt
@@@ -1,0 -1,37 +1,38 @@@
+ --TEST--
+ Exceptions from destruction of an invalid create_sid() return value are preserved
+ --EXTENSIONS--
+ session
+ --FILE--
+ <?php
+
+ class FailingHandler implements SessionHandlerInterface, SessionIdInterface
+ {
+ public function open($path, $name): bool { return true; }
+ public function close(): bool { return true; }
+ public function read($id): string|false { return ''; }
+ public function write($id, $data): bool { return true; }
+ public function destroy($id): bool { return true; }
+ public function gc($max_lifetime): int|false { return 0; }
++ public function validateId($id): bool { return true; }
+
+ #[ReturnTypeWillChange]
+ public function create_sid()
+ {
+ return new class {
+ public function __destruct()
+ {
+ throw new RuntimeException('destructor failed');
+ }
+ };
+ }
+ }
+
+ session_set_save_handler(new FailingHandler());
+ try {
+ session_start();
+ } catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+ }
+ ?>
+ --EXPECT--
+ RuntimeException: destructor failed