This prevents compilation error when compiling PHP by GCC with "-O2 -g -Wall -Werror"
zend_API.c:2754:34: error: array subscript ‘zend_function
{aka const union _zend_function}[0]’ is partly outside array bounds of
‘unsigned char[160]’ [-Werror=array-bounds=]
2754 | if (ZSTR_VAL(fptr->common.function_name)[0] != '_'
For master (8.4-dev) I merged GH-13381. But that PR changes public API
of TSRM, so cannot be used on lower branches.
This patch is a safe workaround for the issue, in combination with a
pre-existing fix using `ifdef ZTS + if (module_started)` inside pgsql
and odbc. The idea is to delay unloading modules until the persistent
resources are destroyed. This will keep the destructor code accessible
in memory.
This is not a proper fix on its own, because we still need the
workaround of not accessing globals after module destruction.
The proper fix is in master.
Closes GH-13388.
When redeclaring an overridden static property with a trait we're removing the
property from the class. However, because the property itself does not belong to
the class we must not free its associated data.
This issue is exposed by 9a250cc9d6 in PHP 8.3+ because duplicate static
properties in traits are no longer skipped, but redeclared.
Fixes GH-12468
When declaring the same static property with a doc block in a class and in a trait,
the doc block of the property in the class is leaked. While at it, possibly fix doc
comment for internal classes.
Close GH-12238
This PR introduces a new way of recursion protection in JSON, var_dump
and friends. It fixes issue in master for __debugInfo and also improves
perf for jsonSerializable in some cases. More info can be found in
GH-10020.
Closes GH-11812
This merges all usages of emitting an offset TypeError into a new ZEND_API function
zend_illegal_container_offset(const zend_string* container, const zval *offset, int type);
Where the container should represent the type on which the access is attempted (e.g. string, array)
The offset zval that is used, where the error message will display its type
The type of access, which should be a BP_VAR_* constant, to get special message for isset/empty/unset
`zend_rc_debug` is not a type and does not really belong in
`zend_types.h`; this allows using `ZEND_RC_MOD_CHECK()` without
including the huge `zend_types.h` header and allows decoupling
circular header dependencies.
* Remove always-false check in zend_lookup_class_ex()
This check is always false because of the undefined behaviour rule that
says a NULL pointer must never be dereferenced: we already dereference name
when checking the cache slot, before the NULL check. So the NULL may be
optimised away by the compiler. It looks like the code isn't even
supposed to work with name being NULL, so just remove the check.
* Remove always-true check in zend_fetch_static_property_address_ex()
* Simplify always-true conditions
zend_update_static_property_ex() returns a zend_result, but the return
value is stored here in a bool. A bool is unsigned on my system, so in
case zend_update_static_property_ex() returns FAILURE (== -1) this gets
converted to 1 instead. This is not a valid zend_result value. This
means that (transitive) callers could mistakingly think the function
succeeded while it did in fact not succeed. Fix it by changing the type
to zend_result.
Closes GH-10691.
`zend_uchar` suggests that the value is an ASCII character, but here,
it's about very small integers. This is misleading, so let's use a
C99 integer instead.
On all architectures currently supported by PHP, `zend_uchar` and
`uint8_t` are identical. This change is only about code readability.
We can't increase the refcount of internal classes during request time.
To work around this problem we simply don't refcount aliases anymore and
add a check in the destruction to skip aliases entirely.
There were also some checks which checked for an alias implicitly by
comparing the refcount, these have been replaced by checking the type of
the zval instead.
This corrects the paren placement to the intended one.
As these functions use zend_result, the success value is zero. Therefore
this has no functional change. The only difference is that this now
hints the compiler optimizer correctly.
Closes GH-10364.
* Emit deprecation warnings when adding dynamic properties to classes during unserialization - this will become an Error in php 9.0.
(Adding dynamic properties in other contexts was already a deprecation warning - the use case of unserialization was overlooked)
* Throw an error when attempting to add a dynamic property to a `readonly` class when unserializing
* Add new serialization methods `__serialize`/`__unserialize` for SplFixedArray to avoid creating deprecated dynamic
properties that would then be added to the backing fixed-size array
* Don't add named dynamic/declared properties (e.g. $obj->foo) of SplFixedArray to the backing array when unserializing
* Update tests to declare properties or to expect the deprecation warning
* Add news entry
Co-authored-by: Tyson Andre <tysonandre775@hotmail.com>
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.
This doesn't have an effect really, but humans and IDEs can struggle to see through the macro soup when they first interact with PHP's source code.
Moreover, this reduces some of the macro expansion hell when they appear in compiler warnings.
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>