Currently we treat paths with null bytes as a TypeError, which is
incorrect, and rather inconsistent, as we treat empty paths as
ValueError. We do this because the error is generated by zpp and
it's easier to always throw TypeError there.
This changes the zpp implementation to throw a TypeError only if
the type is actually wrong and throw ValueError for null bytes.
The error message is also split accordingly, to be more precise.
Closes GH-6094.
When using zpp 'f' or Z_PARAM_FUNC, if the fcc points to a call
trampoline release it immediately and force zend_call_function
to refetch it. This may require additional callability checks
if __call is used, but avoids the need to carefully free fcc
values in all internal functions -- in some cases this is not
simple, as a type error might be triggered by a later argument
in the same zpp call.
This fixes oss-fuzz #25390.
Closes GH-6073.
To perform fast shutdown without full table cleanup we need all
internal functions to be in one continuous chunk. This was
violated when functions were deleted via disable_functions.
This drops the zend_disable_function() API in favor of
zend_disable_functions(), which disables the given list of
functions and performs the necessary rehash afterwards.
Also drop PG(disabled_functions), which is no longer used.
Voidification of Zend API which always succeeded
Use bool argument types instead of int for boolean arguments
Use bool return type for functions which return true/false (1/0)
Use zend_result return type for functions which return SUCCESS/FAILURE as they don't follow normal boolean semantics
Closes GH-6002
From an engine perspective, named parameters mainly add three
concepts:
* The SEND_* opcodes now accept a CONST op2, which is the
argument name. For now, it is looked up by linear scan and
runtime cached.
* This may leave UNDEF arguments on the stack. To avoid having
to deal with them in other places, a CHECK_UNDEF_ARGS opcode
is used to either replace them with defaults, or error.
* For variadic functions, EX(extra_named_params) are collected
and need to be freed based on ZEND_CALL_HAS_EXTRA_NAMED_PARAMS.
RFC: https://wiki.php.net/rfc/named_params
Closes GH-5357.
The (void)_dummy is apparently considered a read of an uninitialized
variable. As it is a _Bool now, which has trap representations, this
is no longer considered legal and results in somewhat odd ubsan
warnings of the form:
runtime error: load of value 0, which is not a valid value for type 'zend_bool' (aka 'bool')
This adds the following APIs:
void zend_call_known_function(
zend_function *fn, zend_object *object, zend_class_entry *called_scope,
zval *retval_ptr, int param_count, zval *params);
void zend_call_known_instance_method(
zend_function *fn, zend_object *object, zval *retval_ptr, int param_count, zval *params);
void zend_call_known_instance_method_with_0_params(
zend_function *fn, zend_object *object, zval *retval_ptr);
void zend_call_known_instance_method_with_1_params(
zend_function *fn, zend_object *object, zval *retval_ptr, zval *param);
void zend_call_known_instance_method_with_2_params(
zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2);
These are used to perform a call if you already have the
zend_function you want to call. zend_call_known_function()
is the base API, the rest are just really thin wrappers around
it for the common case of instance method calls.
Closes GH-5692.
Add ZVAL_CHAR/RETVAL_CHAR/RETURN_CHAR as a shortcut for using
ZVAL_INTERNED_STRING and ZSTR_CHAR.
Add zend_string_init_fast() as a helper for the empty string /
one char interned string / zend_string_init() pattern.
Also add corresponding ZVAL_STRINGL_FAST etc macros.
Closes GH-5684.
We have a bunch of APIs for getting type names and it's sometimes
hard to keep them apart ... make it clear that this is the one
you definitely do not want to use.
Currently, disabling a function only replaces the internal
function handler with one that throws a warning, and a few
places in the engine special-case such functions, such as
function_exists. This leaves us with a Schrödinger's function,
which both does not exist (function_exists returns false) and
does exist (you cannot define a function with the same name).
In particular, this prevents the implementation of robust
polyfills, as reported in https://bugs.php.net/bug.php?id=79382:
if (!function_exists('getallheaders')) {
function getallheaders(...) { ... }
}
If getallheaders() is a disabled function, this code will break.
This patch changes disable_functions to remove the functions from
the function table completely. For all intents and purposes, it
will look like the function does not exist.
This also renders two bits of PHP functionality obsolete and thus
deprecated:
* ReflectionFunction::isDisabled(), as it will no longer be
possible to construct the ReflectionFunction of a disabled
function in the first place.
* get_defined_functions() with $exclude_disabled=false, as
get_defined_functions() now never returns disabled functions.
Fixed bug #79382.
Closes GH-5473.