fix: concurrent env access (#1409)

This commit is contained in:
Alexander Stecher
2025-03-01 14:45:04 +01:00
committed by GitHub
parent 3ba4e257a1
commit c57f741d83
15 changed files with 268 additions and 74 deletions

View File

@@ -160,18 +160,12 @@ static void frankenphp_worker_request_shutdown() {
}
PHPAPI void get_full_env(zval *track_vars_array) {
struct go_getfullenv_return full_env = go_getfullenv(thread_index);
go_getfullenv(thread_index, track_vars_array);
}
for (int i = 0; i < full_env.r1; i++) {
go_string key = full_env.r0[i * 2];
go_string val = full_env.r0[i * 2 + 1];
// create PHP string for the value
zend_string *val_str = zend_string_init(val.data, val.len, 0);
// add to the associative array
add_assoc_str_ex(track_vars_array, key.data, key.len, val_str);
}
void frankenphp_add_assoc_str_ex(zval *track_vars_array, char *key,
size_t keylen, zend_string *val) {
add_assoc_str_ex(track_vars_array, key, keylen, val);
}
/* Adapted from php_request_startup() */
@@ -219,8 +213,20 @@ static int frankenphp_worker_request_startup() {
php_hash_environment();
/* zend_is_auto_global will force a re-import of the $_SERVER global */
zend_is_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER));
/* disarm the $_ENV auto_global to prevent it from being reloaded in worker
* mode */
if (zend_hash_str_exists(&EG(symbol_table), "_ENV", 4)) {
zend_auto_global *env_global;
if ((env_global = zend_hash_find_ptr(
CG(auto_globals), ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_ENV))) !=
NULL) {
env_global->armed = 0;
}
}
/* Unfinish the request */
frankenphp_server_context *ctx = SG(server_context);
ctx->finished = false;
@@ -282,7 +288,7 @@ PHP_FUNCTION(frankenphp_putenv) {
RETURN_FALSE;
}
if (go_putenv(setting, (int)setting_len)) {
if (go_putenv(thread_index, setting, (int)setting_len)) {
RETURN_TRUE;
} else {
RETURN_FALSE;
@@ -308,13 +314,11 @@ PHP_FUNCTION(frankenphp_getenv) {
return;
}
go_string gname = {name_len, name};
struct go_getenv_return result = go_getenv(thread_index, &gname);
struct go_getenv_return result = go_getenv(thread_index, name);
if (result.r0) {
// Return the single environment variable as a string
RETVAL_STRINGL(result.r1->data, result.r1->len);
RETVAL_STR(result.r1);
} else {
// Environment variable does not exist
RETVAL_FALSE;
@@ -748,6 +752,7 @@ void frankenphp_register_bulk(
zend_string *frankenphp_init_persistent_string(const char *string, size_t len) {
/* persistent strings will be ignored by the GC at the end of a request */
zend_string *z_string = zend_string_init(string, len, 1);
zend_string_hash_val(z_string);
/* interned strings will not be ref counted by the GC */
GC_ADD_FLAGS(z_string, IS_STR_INTERNED);
@@ -755,10 +760,6 @@ zend_string *frankenphp_init_persistent_string(const char *string, size_t len) {
return z_string;
}
void frankenphp_release_zend_string(zend_string *z_string) {
zend_string_release(z_string);
}
static void
frankenphp_register_variable_from_request_info(zend_string *zKey, char *value,
bool must_be_present,
@@ -844,9 +845,13 @@ static void frankenphp_log_message(const char *message, int syslog_type_int) {
}
static char *frankenphp_getenv(const char *name, size_t name_len) {
go_string gname = {name_len, (char *)name};
struct go_getenv_return result = go_getenv(thread_index, (char *)name);
return go_sapi_getenv(thread_index, &gname);
if (result.r0) {
return result.r1->val;
}
return NULL;
}
sapi_module_struct frankenphp_sapi_module = {