Skip to content

[pull] master from php:master - #1139

Merged
pull[bot] merged 20 commits into
turkdevops:masterfrom
php:master
Jul 31, 2026
Merged

[pull] master from php:master#1139
pull[bot] merged 20 commits into
turkdevops:masterfrom
php:master

Conversation

@pull

@pull pull Bot commented Jul 31, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

iliaal and others added 20 commits July 31, 2026 11:39
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
* PHP-8.4:
  Free previous state when re-calling Reflection*::__construct()
* 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.
The zend_string conversion in bcb05dc replaced the length check with
zend_string_starts_with(), which also matches on equality. A path equal to
remove_path then hits the non-slash branch, strips its whole length and
produces an empty archive entry name instead of keeping the path.

Closes GH-22973
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.4:
  Parse qualified reflection names with a length-aware search
* 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.
Reuse the part of logic which duplicates in two functions.
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.4:
  Avoid truncation on null bytes in class and function names
* PHP-8.5:
  Avoid truncation on null bytes in class and function names
As we don't need to do function cache shenanigans on those calls.
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
* PHP-8.4:
  Check object_init_ex() in ReflectionMethod::createFromMethodName()
* PHP-8.5:
  Check object_init_ex() in ReflectionMethod::createFromMethodName()
Uses pthread_getthrds_np (so requires pthread linked, by default on ZTS,
needs to be added for NTS). The stack size part is weird, but works in
testing.

An alternative approach is using procfs, but I didn't bother with this
due to it not working on PASE (and the pthread approach works for the
main thread too).
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
* PHP-8.4:
  Resolve the effective property in ReflectionProperty lazy APIs
* 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.
msgget() always creates a queue for IPC_PRIVATE, so the existence probe
in msg_queue_exists() leaks one per call, and the same probe in
msg_get_queue() shadows the IPC_CREAT branch and hands back a queue with
no permission bits. Skip the probe for IPC_PRIVATE. msg_queue_exists(),
msg_get_queue() and sem_get() also passed the zend_long key straight to
msgget()/semget(), where it truncates to key_t; they now reject
out-of-range keys as shmop_open() and shm_attach() have since GH-9945.

Closes GH-22956
@pull pull Bot locked and limited conversation to collaborators Jul 31, 2026
@pull pull Bot added the ⤵️ pull label Jul 31, 2026
@pull
pull Bot merged commit a0d06f1 into turkdevops:master Jul 31, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants