Updates the output of `ReflectionClassConstant::__toString()` and
`ReflectionConstant::__toString()`, as well as the other ways that class
constants are printed, e.g. `ReflectionClass::__toString()`.
* PHP-8.5:
NEWS for PHP 8.5
NEWS for PHP 8.4
GH-22905: avoid truncation on null bytes in reflection exceptions
Reflection: Add regression tests for error messages with null bytes
* PHP-8.4:
NEWS for PHP 8.4
GH-22905: avoid truncation on null bytes in reflection exceptions
Reflection: Add regression tests for error messages with null bytes
In addition to the fixes within the reflection extension, support for error
strings with null bytes was added to `zend_throw_error()` and
`zend_throw_exception_ex()`. The changes to `zend_throw_exception_ex()` are a
partial backport of #16684.
Continues #22565 for four sites that were missed: _class_exists_impl(),
function_exists(), pdo_stmt.c's dbstmt_method_get(), ReflectionClass::
hasMethod()/getMethod(), and phpdbg's print func/method commands. No
behavior change.
* PHP-8.5:
Resolve the effective property in ReflectionProperty lazy APIs
master takes the property info and scope directly in
reflection_property_get_effective_prop() and
reflection_property_check_lazy_compatible(), so both call sites are
adapted to those signatures here.
skipLazyInitialization() and isLazy() indexed the object with the
property info of the reflected scope. When a child adds hooks to a plain
parent property the child gets its own storage slot, so a parent-scoped
ReflectionProperty read and wrote the dead parent slot: isLazy() reported
false and skipLazyInitialization() was a silent no-op. Resolve the
effective property first, as getRawValue(), setRawValue() and
setRawValueWithoutLazyInitialization() already do.
Closes GH-22969
The result was ignored, so calling the factory on an uninstantiable
subclass ran on a NULL zend_object: object_init_ex() throws, sets the
return value to NULL and reports FAILURE, and Z_REFLECTION_P() then
offsets backwards from that NULL. Other object_init_ex() calls in this
file already test the result.
Closes GH-22978
Follow-up to GH-22681. _class_string() and _function_string() still
formatted the class name and the function name with %s, so
Reflection*::__toString() cut them at the first NUL. Anonymous class
names embed one, both directly and inside the name of a closure declared
in such a class.
Closes GH-22971
* PHP-8.5:
Parse qualified reflection names with a length-aware search
Master already carries the const declarations the backport introduces, so
the resolution keeps them and takes only the two zend_memnstr() calls.
ReflectionMethod::__construct(), ReflectionMethod::createFromMethodName()
and ReflectionClass::getProperty() split "Class::member" with strstr(),
which stops at the first NUL. Anonymous class names embed one, so a name
obtained from ReflectionClass::getName() was rejected. Use zend_memnstr()
over the whole string instead.
Closes GH-22970
* PHP-8.5:
Free previous state when re-calling Reflection*::__construct()
Master additionally stores the reflected closure in intern->obj for the
invoke() identity check, so the merge releases the previous object before
overwriting it and clears the slot when re-constructing onto a named
method.
ReflectionMethod::__construct() overwrote intern->ptr without releasing
the previous Closure::__invoke() trampoline, and
ReflectionClassConstant::__construct() overwrote the $name and $class
slots without dropping their previous references. ReflectionFunction,
ReflectionParameter and ReflectionProperty already release prior state
on re-entry.
Closes GH-22968
Align with other Reflection exceptions for missing class properties (and
methods, constants, etc.) by changing the message to
"Property %s::$%s does not exist".
Improve error messages from `reflection_property_check_lazy_compatible()`, as
triggered by both `ReflectionProperty::setRawValueWithoutLazyInitialization()`
and `ReflectionProperty::skipLazyInitialization()`. Say "cannot" instead of
"can not", and include parentheses after the method name.
Use `uint32_t` for values that are really `uint32_t`, like constant module
numbers and the result from `zend_hash_num_elements()`. Use `uint32_t` for
counting up, when values should never be negative. Adjust format specifiers to
use `PRIu32` rather than `%d` for the uint32_t values.