Skip to content

Commit 358b1b6

Browse files
committed
fix(worker): reset ini and session: support PHP8.2
1 parent 961f0d3 commit 358b1b6

2 files changed

Lines changed: 38 additions & 29 deletions

File tree

frankenphp.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ __thread bool is_worker_thread = false;
7676
__thread zval *os_environment = NULL;
7777
__thread HashTable *worker_ini_snapshot = NULL;
7878

79-
/* Session user handler names (same structure as PS(mod_user_names)) */
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. */
8082
typedef struct {
8183
zval ps_open;
8284
zval ps_close;
@@ -89,6 +91,13 @@ typedef struct {
8991
zval ps_update_timestamp;
9092
} session_user_handlers;
9193

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+
92101
__thread session_user_handlers *worker_session_handlers_snapshot = NULL;
93102

94103
void frankenphp_update_local_thread_context(bool is_worker) {
@@ -247,8 +256,8 @@ static void frankenphp_restore_ini(void) {
247256
/* Entry was not in snapshot: collect for restore to startup default */
248257
if (restore_count >= restore_capacity) {
249258
restore_capacity = restore_capacity ? restore_capacity * 2 : 8;
250-
entries_to_restore =
251-
erealloc(entries_to_restore, restore_capacity * sizeof(zend_string *));
259+
entries_to_restore = erealloc(entries_to_restore,
260+
restore_capacity * sizeof(zend_string *));
252261
}
253262
entries_to_restore[restore_count++] = zend_string_copy(entry_name);
254263
} else if (!zend_string_equals(ini_entry->value, snapshot_value)) {
@@ -285,7 +294,7 @@ static void frankenphp_snapshot_session_handlers(void) {
285294
}
286295

287296
/* Check if user session handlers are defined */
288-
if (Z_ISUNDEF(PS(mod_user_names).ps_open)) {
297+
if (Z_ISUNDEF(PS_MOD_USER_NAMES(ps_open))) {
289298
return; /* No user handlers to snapshot */
290299
}
291300

@@ -295,12 +304,12 @@ static void frankenphp_snapshot_session_handlers(void) {
295304
}
296305

297306
/* Copy each handler zval with incremented reference count */
298-
#define SNAPSHOT_HANDLER(name) \
299-
if (!Z_ISUNDEF(PS(mod_user_names).name)) { \
300-
ZVAL_COPY(&worker_session_handlers_snapshot->name, \
301-
&PS(mod_user_names).name); \
307+
#define SNAPSHOT_HANDLER(handler) \
308+
if (!Z_ISUNDEF(PS_MOD_USER_NAMES(handler))) { \
309+
ZVAL_COPY(&worker_session_handlers_snapshot->handler, \
310+
&PS_MOD_USER_NAMES(handler)); \
302311
} else { \
303-
ZVAL_UNDEF(&worker_session_handlers_snapshot->name); \
312+
ZVAL_UNDEF(&worker_session_handlers_snapshot->handler); \
304313
}
305314

306315
SNAPSHOT_HANDLER(ps_open);
@@ -323,13 +332,13 @@ static void frankenphp_restore_session_handlers(void) {
323332
}
324333

325334
/* Restore each handler zval */
326-
#define RESTORE_HANDLER(name) \
327-
if (!Z_ISUNDEF(worker_session_handlers_snapshot->name)) { \
328-
if (!Z_ISUNDEF(PS(mod_user_names).name)) { \
329-
zval_ptr_dtor(&PS(mod_user_names).name); \
335+
#define RESTORE_HANDLER(handler) \
336+
if (!Z_ISUNDEF(worker_session_handlers_snapshot->handler)) { \
337+
if (!Z_ISUNDEF(PS_MOD_USER_NAMES(handler))) { \
338+
zval_ptr_dtor(&PS_MOD_USER_NAMES(handler)); \
330339
} \
331-
ZVAL_COPY(&PS(mod_user_names).name, \
332-
&worker_session_handlers_snapshot->name); \
340+
ZVAL_COPY(&PS_MOD_USER_NAMES(handler), \
341+
&worker_session_handlers_snapshot->handler); \
333342
}
334343

335344
RESTORE_HANDLER(ps_open);
@@ -356,9 +365,9 @@ static void frankenphp_cleanup_worker_state(void) {
356365

357366
/* Free session handlers snapshot */
358367
if (worker_session_handlers_snapshot != NULL) {
359-
#define FREE_HANDLER(name) \
360-
if (!Z_ISUNDEF(worker_session_handlers_snapshot->name)) { \
361-
zval_ptr_dtor(&worker_session_handlers_snapshot->name); \
368+
#define FREE_HANDLER(handler) \
369+
if (!Z_ISUNDEF(worker_session_handlers_snapshot->handler)) { \
370+
zval_ptr_dtor(&worker_session_handlers_snapshot->handler); \
362371
}
363372

364373
FREE_HANDLER(ps_open);

frankenphp_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ func TestRequestSuperGlobalConditional_worker(t *testing.T) {
341341
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
342342
if i%2 == 0 {
343343
// Even requests: don't use $_REQUEST
344-
body, _:= testGet(fmt.Sprintf("http://example.com/request-superglobal-conditional.php?val=%d", i), handler, t)
344+
body, _ := testGet(fmt.Sprintf("http://example.com/request-superglobal-conditional.php?val=%d", i), handler, t)
345345
assert.Contains(t, body, "SKIPPED")
346346
assert.Contains(t, body, fmt.Sprintf("'val' => '%d'", i))
347347
} else {
@@ -1135,7 +1135,7 @@ func TestSessionHandlerReset_worker(t *testing.T) {
11351135
resp1, err := http.Get(ts.URL + "/session-handler.php?action=set_handler_and_start&value=test1")
11361136
assert.NoError(t, err)
11371137
body1, _ := io.ReadAll(resp1.Body)
1138-
resp1.Body.Close()
1138+
_ = resp1.Body.Close()
11391139

11401140
body1Str := string(body1)
11411141
assert.Contains(t, body1Str, "HANDLER_SET_AND_STARTED")
@@ -1147,7 +1147,7 @@ func TestSessionHandlerReset_worker(t *testing.T) {
11471147
resp2, err := http.Get(ts.URL + "/session-handler.php?action=start_without_handler")
11481148
assert.NoError(t, err)
11491149
body2, _ := io.ReadAll(resp2.Body)
1150-
resp2.Body.Close()
1150+
_ = resp2.Body.Close()
11511151

11521152
body2Str := string(body2)
11531153

@@ -1179,15 +1179,15 @@ func TestIniLeakBetweenRequests_worker(t *testing.T) {
11791179
resp1, err := http.Get(ts.URL + "/ini-leak.php?action=change_ini")
11801180
assert.NoError(t, err)
11811181
body1, _ := io.ReadAll(resp1.Body)
1182-
resp1.Body.Close()
1182+
_ = resp1.Body.Close()
11831183

11841184
assert.Contains(t, string(body1), "INI_CHANGED")
11851185

11861186
// Request 2: Check if INI values leaked from request 1
11871187
resp2, err := http.Get(ts.URL + "/ini-leak.php?action=check_ini")
11881188
assert.NoError(t, err)
11891189
body2, _ := io.ReadAll(resp2.Body)
1190-
resp2.Body.Close()
1190+
_ = resp2.Body.Close()
11911191

11921192
body2Str := string(body2)
11931193
t.Logf("Response: %s", body2Str)
@@ -1212,7 +1212,7 @@ func TestSessionHandlerPreLoopPreserved_worker(t *testing.T) {
12121212
resp1, err := http.Get(ts.URL + "/worker-with-session-handler.php?action=check")
12131213
assert.NoError(t, err)
12141214
body1, _ := io.ReadAll(resp1.Body)
1215-
resp1.Body.Close()
1215+
_ = resp1.Body.Close()
12161216

12171217
body1Str := string(body1)
12181218
t.Logf("Request 1 response: %s", body1Str)
@@ -1225,7 +1225,7 @@ func TestSessionHandlerPreLoopPreserved_worker(t *testing.T) {
12251225
resp2, err := http.Get(ts.URL + "/worker-with-session-handler.php?action=use_session")
12261226
assert.NoError(t, err)
12271227
body2, _ := io.ReadAll(resp2.Body)
1228-
resp2.Body.Close()
1228+
_ = resp2.Body.Close()
12291229

12301230
body2Str := string(body2)
12311231
t.Logf("Request 2 response: %s", body2Str)
@@ -1240,7 +1240,7 @@ func TestSessionHandlerPreLoopPreserved_worker(t *testing.T) {
12401240
resp3, err := http.Get(ts.URL + "/worker-with-session-handler.php?action=check")
12411241
assert.NoError(t, err)
12421242
body3, _ := io.ReadAll(resp3.Body)
1243-
resp3.Body.Close()
1243+
_ = resp3.Body.Close()
12441244

12451245
body3Str := string(body3)
12461246
t.Logf("Request 3 response: %s", body3Str)
@@ -1261,7 +1261,7 @@ func TestIniPreLoopPreserved_worker(t *testing.T) {
12611261
resp1, err := http.Get(ts.URL + "/worker-with-ini.php?action=check")
12621262
assert.NoError(t, err)
12631263
body1, _ := io.ReadAll(resp1.Body)
1264-
resp1.Body.Close()
1264+
_ = resp1.Body.Close()
12651265

12661266
body1Str := string(body1)
12671267
t.Logf("Request 1 response: %s", body1Str)
@@ -1276,7 +1276,7 @@ func TestIniPreLoopPreserved_worker(t *testing.T) {
12761276
resp2, err := http.Get(ts.URL + "/worker-with-ini.php?action=change_ini")
12771277
assert.NoError(t, err)
12781278
body2, _ := io.ReadAll(resp2.Body)
1279-
resp2.Body.Close()
1279+
_ = resp2.Body.Close()
12801280

12811281
body2Str := string(body2)
12821282
t.Logf("Request 2 response: %s", body2Str)
@@ -1288,7 +1288,7 @@ func TestIniPreLoopPreserved_worker(t *testing.T) {
12881288
resp3, err := http.Get(ts.URL + "/worker-with-ini.php?action=check")
12891289
assert.NoError(t, err)
12901290
body3, _ := io.ReadAll(resp3.Body)
1291-
resp3.Body.Close()
1291+
_ = resp3.Body.Close()
12921292

12931293
body3Str := string(body3)
12941294
t.Logf("Request 3 response: %s", body3Str)

0 commit comments

Comments
 (0)