-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix CGI with auto_globals_jit=0 #19870
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There's no need to call zend_is_auto_global(), which will read the uninitialized armed field. If the env is not yet initialized, we'll fall back to php_php_import_environment_variables().
147bfc8
to
5bfb86f
Compare
@bukka Also added you as a reviewer since this code is quite similar to php-fpm. So you might have the most real experience with this code. 🙂
I remember fixing something related in FPM but will need to refresh my mind and double check it. I plan to also look into those argc deprecation changes and logic around that to see if anything could be improved there. I should have a slot for this in a week starting Oct 7.
@bukka Thanks. This currently breaks nightly, I'd prefer not to keep it red for so long. Maybe we can merge this for master now and backport later, once you've verified?
Maybe we can merge this for master now and backport later, once you've verified?
@iluuu1994 Sounds good to me
It took me a while to understand what is happening here and the PR description doesn't properly explain, why the field is uninitialized only in non-JIT mode. It works like this:
zend_activate_auto_globals
is being called.- Since SERVER is not jitted,
->auto_global_callback()
is being called to initialize->armed
. - This is
php_auto_globals_create_server()
. - Which then calls
php_register_server_variables()
. - Which calls
register_server_variables()
- Which calls
cgi_php_import_environment_variables()
- Which calls
zend_is_auto_global
forENV
- Which then depends on the uninitialized
->armed
field forENV
.
An alternative fix would be initializing ENV before SERVER:
zend_register_auto_global(zend_string_init_interned("_GET", sizeof("_GET")-1, 1), 0, php_auto_globals_create_get);
zend_register_auto_global(zend_string_init_interned("_POST", sizeof("_POST")-1, 1), 0, php_auto_globals_create_post);
zend_register_auto_global(zend_string_init_interned("_COOKIE", sizeof("_COOKIE")-1, 1), 0, php_auto_globals_create_cookie);
- zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER), PG(auto_globals_jit), php_auto_globals_create_server);
zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_ENV), PG(auto_globals_jit), php_auto_globals_create_env);
+ zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER), PG(auto_globals_jit), php_auto_globals_create_server);
zend_register_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_REQUEST), PG(auto_globals_jit), php_auto_globals_create_request);
zend_register_auto_global(zend_string_init_interned("_FILES", sizeof("_FILES")-1, 1), 0, php_auto_globals_create_files);
This would also avoid calling php_php_import_environment_variables
twice: Once to initialize $_SERVER and once to initialize $_ENV.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer my suggested diff to avoid the duplicate import that the original logic tried to avoid (ensuring that ENV is definitely in sync with SERVER). Please also include my analysis in the commit message.
I went with a different fix that just makes sure armed
is properly initialized. This prevents the duplicate import Tim mentioned. The commit was discussed via DM with Tim and merged directly so it makes the 8.5 RC1 cut. I'll create a new issue to backport this commit so we don't forget.
There's no need to call zend_is_auto_global(), which will read the uninitialized armed field. If the env is not yet initialized, we'll fall back to php_php_import_environment_variables().
See https://github.com/php/php-src/actions/runs/17815318830/job/50647381504. Exposed by GH-19833.