Updates the output of `ReflectionClassConstant::__toString()` and
`ReflectionConstant::__toString()`, as well as the other ways that class
constants are printed, e.g. `ReflectionClass::__toString()`.
Add regression tests for the output of `ReflectionClassConstant::__toString()`
and `ReflectionConstant::__toString()` when the value of the constant is
boolean `true` or `false`. The `true` cases are already covered by some
existing tests, but it seems that the `false` cases are currently untested.
Headers required by the generated code (zend_attributes.h, zend_constants.h, zend_enum.h) are collected during generation and emitted as includes at the top of the arginfo file, with the same preprocessor conditions and PHP version guards as the code that needs them.
Removes the manual zend_attributes.h and zend_enum.h includes from sources that only needed them for the arginfo file they include.
* 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.
Add tests for the four error cases in
`reflection_property_check_lazy_compatible()`, as triggered by both
`ReflectionProperty::setRawValueWithoutLazyInitialization()` and
`ReflectionProperty::skipLazyInitialization()`. While some of these errors are
covered by existing tests, having all of the errors in one place will make it
easier to see the changes when the error messages are improved.