* zend_ini: Make `ZEND_INI_GET_ADDR()` return a `void*` pointer
Since the actual type of the storage location is not known, a `void*` is more
appropriate and avoids explicit casts that are no more safe than the implicit
cast from `void*`.
* tree-wide: Remove explicit casts of `ZEND_INI_GET_ADDR()`
* UPGRADING.INTERNALS
The primary motivation for this change is that this sort of functionality should reside in core and not in an extension.
The reason being is that this causes issues in regard to extension dependencies and resolution,
something that prevents GH-14544.
Since the ini message handlers already check for basedir, we need to
drop the basedir check from ini_set. Then we also fix the exceptional
case for the empty string: it should bypass the basedir check.
Furthermore, there was a regression introduced with the error_log
"syslog" check in ddfe269a (inverted check), so we fix that as well.
Closes GH-19487
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#remove_disable_classes_ini_setting
This took longer to merge than expected but the initial motivation from 2 years ago still applied:
As described in the email to the PHP internals list [1] this feature is fundamentally broken and pointless.
Only internal classes can be disable which brings the following observation. On a minimal build of PHP, with only the mandatory extensions enabled, there are 148 classes/interfaces/traits defined. [2]
Other than the SPL ones (and even then), disabling any of these classes will cause issues within the engine.
Moreover, the SPL ones are not a security concern.
Therefore, any other class that can be disabled must come from an extension that can be disabled altogether. And "disabling" a class from an extension without disabling said extension will render it useless anyway.
If a hosting provided is concerned about an extension, then it should not enable it in the first place. Not break it ad hoc.
Considering the above, I cannot see how this functionality was ever useful.
This is in stark contrast to the disable_functions INI setting, which can be used to selectively remove functionality of an extension without breaking it overall.
What makes this setting particularly broken is that it does not unregister the class, it only overwrites the create CE handler to emit a warning and purge the properties and function hashtables. This leads to various use after free, segfaults, and broken expectations for the engine and extensions which define said classes. On top of that, it is possible to actually instantiate such a class (and even classes which actually disallow this like ext/imap) in userland, and pass it to function that are typed against said class without raising a TypeError. However, when trying to do anything with said object stuff is going to explode in countless ways.
[1] https://news-web.php.net/php.internals/120896
[2] https://gist.github.com/Girgias/63d55ba1e50b580412b004046daed02b
The shadow key is refreshed when resetting the memory manager between two
requests. But in forking SAPIs the first request of a child process inherits the
shadow key of the parent. As a result, a leak of the shadow key during the first
request of one process gives away the shadow key used during the first request
of other processes. This makes the key refresh mechanism less useful.
Here I ensure that we refresh the shadow key after a fork. We can not reset the
manager as there may be active allocations. Instead, we have to recompute shadow
pointers with the new key.
Closes GH-16765
This allows us to avoid a call to `zend_ini_str` which took 6% of the
profile on my i7-4790 for a call to `http_build_query`. Now we can just
grab the value from the globals.
In other files this can avoid some length recomputations.
The problem is that `php_request_shutdown` calls `php_deactivate_ticks` prior
to running destructors and the shutdown functions and finalizing output
handlers.
So if a destructor or shutdown function re-registers a tick function,
then the user tick functions handler will be added back to `PG(tick_functions)`.
When the next request happens, the list `PG(tick_functions)` still contains an
entry to call the user tick functions (added in the previous request
during shutdown). This causes a NULL deref eventually because
`run_user_tick_functions` assumes that if it is called then
`BG(user_tick_functions)` must be non-NULL.
Fix this by moving the tick handler deactivation.
Closes GH-18047.
If `_DEBUG` is set, assertion failures and errors are directed to a
debug message window by default[1]. That causes a process to hang,
since these dialogs are modal. While we already cater to assertion
failures, errors have apparently been overlooked.
We choose a minimal fix for BC reasons; although passing `0` as
`reportMode` is undocumented, it obviously works fine for a long time.
We may consider to improve on this for the `master` branch.
[1] <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/crtsetreportmode>
Closes GH-16850.
This information can be occasionally useful, and would otherwise need
to be parsed from `phpinfo()` output.
However, maybe more importantly we unify the build date between what is
given by `php -v` and `php -i`, since these compilation units are not
necessarily preprocessed within the same second.
Closes GH-16747.
We also add zend_map_ptr_static, so that we do not incur the overhead of constantly recreating the internal run_time_cache pointers on each request.
This mechanism might be extended for mutable_data of internal classes too.
* Show build provider information in "php -v"
Vendors such as distributions can set the `PHP_BUILD_PROVIDER`
variable, that gets printed in phpinfo. However, I find that users check
`php -v` more often than phpinfo to see what PHP they're running. The
problem with this is that it does not show that build provider
information.
This change makes the build provider information printed on an
additional line of the version information.
* Put on same line so it works with or without env var
Unbreaks build without PHP_BUILD_PROVIDER set.
* change wording in provider version text
better grammatically; many different possibilities here though
* Unify SAPI version printing
This makes it so that all of the SAPIs share the same code for printing
version information. This is useful in case of any future changes to the
version information, such as i.e. adding build provider to the output.
* Make include for php_print_version explicit
* Preserve phpdbg version and output channel
php_printf doesn't have same semantics, as phpdbg_out could be on a
different output than stdout/err. Also add the phpdbg version (in case
it differs from PHP's, to keep similar output before this PR)
* remove size variables
we don't use them and CI doesn't like unused variables
* Fix format string insecurity