44#include <Zend/zend_interfaces.h>
55#include <Zend/zend_types.h>
66#include <errno.h>
7- #include <ext/session/php_session.h>
87#include <ext/spl/spl_exceptions.h>
98#include <ext/standard/head.h>
109#include <inttypes.h>
@@ -76,41 +75,6 @@ __thread bool is_worker_thread = false;
7675__thread zval * os_environment = NULL ;
7776__thread HashTable * worker_ini_snapshot = NULL ;
7877
79- /* Session user handler names (same structure as PS(mod_user_names)).
80- * In PHP 8.2, mod_user_names is a union with .name.ps_* access.
81- * In PHP 8.3+, mod_user_names is a direct struct with .ps_* access. */
82- typedef struct {
83- zval ps_open ;
84- zval ps_close ;
85- zval ps_read ;
86- zval ps_write ;
87- zval ps_destroy ;
88- zval ps_gc ;
89- zval ps_create_sid ;
90- zval ps_validate_sid ;
91- zval ps_update_timestamp ;
92- } session_user_handlers ;
93-
94- /* Macro to access PS(mod_user_names) handlers across PHP versions */
95- #if PHP_VERSION_ID >= 80300
96- #define PS_MOD_USER_NAMES (handler ) PS(mod_user_names).handler
97- #else
98- #define PS_MOD_USER_NAMES (handler ) PS(mod_user_names).name.handler
99- #endif
100-
101- #define FOR_EACH_SESSION_HANDLER (op ) \
102- op(ps_open); \
103- op(ps_close); \
104- op(ps_read); \
105- op(ps_write); \
106- op(ps_destroy); \
107- op(ps_gc); \
108- op(ps_create_sid); \
109- op(ps_validate_sid); \
110- op(ps_update_timestamp)
111-
112- __thread session_user_handlers * worker_session_handlers_snapshot = NULL ;
113-
11478void frankenphp_update_local_thread_context (bool is_worker ) {
11579 is_worker_thread = is_worker ;
11680}
@@ -155,13 +119,6 @@ static void frankenphp_reset_super_globals() {
155119 zval * files = & PG (http_globals )[TRACK_VARS_FILES ];
156120 zval_ptr_dtor_nogc (files );
157121 memset (files , 0 , sizeof (* files ));
158-
159- /* $_SESSION must be explicitly deleted from the symbol table.
160- * Unlike other superglobals, $_SESSION is stored in EG(symbol_table)
161- * with a reference to PS(http_session_vars). The session RSHUTDOWN
162- * only decrements the refcount but doesn't remove it from the symbol
163- * table, causing data to leak between requests. */
164- zend_hash_str_del (& EG (symbol_table ), "_SESSION" , sizeof ("_SESSION" ) - 1 );
165122 }
166123 zend_end_try ();
167124
@@ -300,59 +257,6 @@ static void frankenphp_restore_ini(void) {
300257 }
301258}
302259
303- /* Save session user handlers set before the worker loop.
304- * This allows frameworks to define custom session handlers that persist. */
305- static void frankenphp_snapshot_session_handlers (void ) {
306- if (worker_session_handlers_snapshot != NULL ) {
307- return ; /* Already snapshotted */
308- }
309-
310- /* Check if session module is loaded */
311- if (zend_hash_str_find_ptr (& module_registry , "session" ,
312- sizeof ("session" ) - 1 ) == NULL ) {
313- return ; /* Session module not available */
314- }
315-
316- /* Check if user session handlers are defined */
317- if (Z_ISUNDEF (PS_MOD_USER_NAMES (ps_open ))) {
318- return ; /* No user handlers to snapshot */
319- }
320-
321- worker_session_handlers_snapshot = emalloc (sizeof (session_user_handlers ));
322-
323- /* Copy each handler zval with incremented reference count */
324- #define SNAPSHOT_HANDLER (h ) \
325- if (!Z_ISUNDEF(PS_MOD_USER_NAMES(h))) { \
326- ZVAL_COPY(&worker_session_handlers_snapshot->h, &PS_MOD_USER_NAMES(h)); \
327- } else { \
328- ZVAL_UNDEF(&worker_session_handlers_snapshot->h); \
329- }
330-
331- FOR_EACH_SESSION_HANDLER (SNAPSHOT_HANDLER );
332-
333- #undef SNAPSHOT_HANDLER
334- }
335-
336- /* Restore session user handlers from snapshot after RSHUTDOWN freed them. */
337- static void frankenphp_restore_session_handlers (void ) {
338- if (worker_session_handlers_snapshot == NULL ) {
339- return ;
340- }
341-
342- /* Restore each handler zval.
343- * Session RSHUTDOWN already freed the handlers via zval_ptr_dtor and set
344- * them to UNDEF, so we don't need to destroy them again. We simply copy
345- * from the snapshot (which holds its own reference). */
346- #define RESTORE_HANDLER (h ) \
347- if (!Z_ISUNDEF(worker_session_handlers_snapshot->h)) { \
348- ZVAL_COPY(&PS_MOD_USER_NAMES(h), &worker_session_handlers_snapshot->h); \
349- }
350-
351- FOR_EACH_SESSION_HANDLER (RESTORE_HANDLER );
352-
353- #undef RESTORE_HANDLER
354- }
355-
356260/* Free worker state when the worker script terminates. */
357261static void frankenphp_cleanup_worker_state (void ) {
358262 /* Free INI snapshot */
@@ -361,21 +265,6 @@ static void frankenphp_cleanup_worker_state(void) {
361265 FREE_HASHTABLE (worker_ini_snapshot );
362266 worker_ini_snapshot = NULL ;
363267 }
364-
365- /* Free session handlers snapshot */
366- if (worker_session_handlers_snapshot != NULL ) {
367- #define FREE_HANDLER (h ) \
368- if (!Z_ISUNDEF(worker_session_handlers_snapshot->h)) { \
369- zval_ptr_dtor(&worker_session_handlers_snapshot->h); \
370- }
371-
372- FOR_EACH_SESSION_HANDLER (FREE_HANDLER );
373-
374- #undef FREE_HANDLER
375-
376- efree (worker_session_handlers_snapshot );
377- worker_session_handlers_snapshot = NULL ;
378- }
379268}
380269
381270/* Adapted from php_request_shutdown */
@@ -416,7 +305,6 @@ bool frankenphp_shutdown_dummy_request(void) {
416305 * The framework has set these up before the worker loop, and we want
417306 * to preserve them. Session RSHUTDOWN will free the handlers. */
418307 frankenphp_snapshot_ini ();
419- frankenphp_snapshot_session_handlers ();
420308
421309 frankenphp_worker_request_shutdown ();
422310
@@ -488,12 +376,6 @@ static int frankenphp_worker_request_startup() {
488376 module -> request_startup_func (module -> type , module -> module_number );
489377 }
490378 }
491-
492- /* Restore session handlers AFTER session RINIT.
493- * Session RSHUTDOWN frees mod_user_names callbacks, so we must restore
494- * them before user code runs. This must happen after RINIT because
495- * session RINIT may reset some state. */
496- frankenphp_restore_session_handlers ();
497379 }
498380 zend_catch { retval = FAILURE ; }
499381 zend_end_try ();
0 commit comments