The problem is that we're using the variable_ptr in the opcode handler
*after* it has already been destroyed. The solution is to create a
specialised version of zend_assign_to_variable which takes in two
destination zval pointers.
Closes GH-10524
This debug code is part of arginfo validation. This validation will
never trigger properly because the OR operation makes the first if
always true. Fix it by changing to an AND.
Closes GH-10417
Signed-off-by: George Peter Banyard <girgias@php.net>
The assertion failure was triggered in a debug code-path that validates
property types for internal classes.
zend_verify_internal_read_property_type was called with retval being a
reference, which is not allowed because that function eventually calls to
i_zend_check_property_type, which does not expect a reference.
The non-debug code-path already takes into account that retval can be a
reference, as it optionally dereferences retval.
Add a dereference in zend_verify_internal_read_property_type just before
the call to zend_verify_property_type, which is how other callers often
behave as well.
The issue was that we didn't compute enough cache slots for DNF types.
Nor progressed throught the CE's in the cache slot, meaning we were only checking if the value passed
satisfied the first type of the nested intersection type.
This avoids a possible significant performance penalty, when some leaf function was observed, deep in the stack.
As a side effect, we are not iterating over prev_execute_data anymore and thus, non-observed fake frames, possibly on stack, cannot have any impact on the observer anymore (especially within zend_observer_fcall_end_all).
Saving the previous observer happens now directly on the VM stack. If there is any observer, function frames are allocated an extra zval (the last temporary), which will, on observed frames, contain the previous observed frame address.
There are two main motivations to this:
a) The logic for handling internal and userland observation can be unified.
b) Unwinding of observed functions on a bailout does notably not include observers. Even if users of observers were to ensure such handling themselves, it would be impossible to retain the relative ordering - either the user has to unwind all internal observed frames before the automatic unwinding (zend_observer_fcall_end_all) or afterwards, but not properly interleaved.
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
Implements https://wiki.php.net/rfc/partially-supported-callables-expand-deprecation-notices
so that uses of "self" and "parent" in is_callable() and callable
type constraints now raise a deprecation notice, independent of the
one raised when and if the callable is actually invoked.
A new flag is added to the existing check_flags parameter of
zend_is_callable / zend_is_callable_ex, for use in internal calls
that would otherwise repeat the notice multiple times. In particular,
arguments to internal function calls are checked first based on
arginfo, and then again during ZPP, so the former suppresses the
deprecation notice.
Some existing tests which raised this deprecation have been updated
to avoid the syntax, but the existing version retained for maximum
regression coverage until it is made an error.
With thanks to Juliette Reinders Folmer for the RFC and initial
investigation.
Closes GH-8823.
RFC: https://wiki.php.net/rfc/dnf_types
This allows to combine union and intersection types together in the following form (A&B)|(X&Y)|T but not of the form (X|A)&(Y|B) or (X|A)&(Y|B)|T.
* Improve union type parsing
Co-authored-by: Sara Golemon <pollita@php.net>
This does a compile time transformation of ``iterable`` into ``Traversable|array`` which simplifies some of the LSP variance handling.
The arginfo generation script from stubs is updated to produce a union type when it encounters the type ``iterable``
Extension functions which do not regenerate the arginfo, or write them manually are still supported by mimicking the compile time transformation while registering the function.
Type Reflection is preserved for single ``iterable`` (and ``?iterable``) to produce a ReflectionNamedType with name ``iterable``, however usage of ``iterable`` in union types will be converted to ``array|Traversable``
This is done by adding a new zend_atomic_bool type. The type
definition is only available for compiler alignment and size info; it
should be treated as opaque and only the zend_atomic_bool_* family of
functions should be used.
Note that directly using atomic_bool is complicated. All C++ compilers
stdlibs that I checked typedef atomic_bool to std::atomic<bool>, which
can't be used in an extern "C" section, and there's at least one usage
of this in core, and probably more outside of it.
So, instead use platform specific functions, preferring compiler
intrinsics.
This code duplication was introduced by commit 85f35a8fc1 ("Separate
unspecializeble code of INCLIDE_OR_EVAL into helper functions") for no
obvious reason.
* ext/oci8: use zend_string_equals()
Eliminate duplicate code.
* main/php_variables: use zend_string_equals_literal()
Eliminate duplicate code.
* Zend/zend_string: add zend_string_equals_cstr()
Allows eliminating duplicate code.
* Zend, ext/{opcache,standard}, main/output: use zend_string_equals_cstr()
Eliminate duplicate code.
* Zend/zend_string: add zend_string_starts_with()
* ext/{opcache,phar,spl,standard}: use zend_string_starts_with()
This adds missing length checks to several callers, e.g. in
cache_script_in_shared_memory(). This is important when the
zend_string is shorter than the string parameter, when memcmp()
happens to check backwards; this can result in an out-of-bounds memory
access.