Skip to content

Fix GH-21478: Forward read_property to real instance for initialized lazy proxies#21480

Open
iliaal wants to merge 1 commit intophp:masterfrom
iliaal:fix/gh-21478-proxy-read-property-guard
Open

Fix GH-21478: Forward read_property to real instance for initialized lazy proxies#21480
iliaal wants to merge 1 commit intophp:masterfrom
iliaal:fix/gh-21478-proxy-read-property-guard

Conversation

@iliaal
Copy link
Contributor

@iliaal iliaal commented Mar 21, 2026

Summary

zend_std_read_property() was calling __get/__isset on an initialized lazy proxy before forwarding to the real instance. This produced double magic method invocations when the real instance's __get accessed the proxy -- the proxy's own guard was clear, so __get fired on the proxy too.

For pure reads (BP_VAR_R, BP_VAR_IS), forward directly to the real instance before attempting magic methods on the proxy. Write contexts (BP_VAR_W/RW) are excluded since read_property with those types is a fallback from get_property_ptr_ptr for reference operations.

Also updates gh18038-004 and gh18038-007 test expectations to match -- these tests previously asserted the double-call behavior that GH-21478 reports as a bug.

Fixes #21478

…ed lazy proxies

When an initialized lazy proxy has __get/__isset, zend_std_read_property()
was calling the magic method on the proxy itself before forwarding to the
real instance at uninit_error. This caused double invocations: __get fired
on both the real instance and the proxy.

For pure reads (BP_VAR_R, BP_VAR_IS), forward directly to the real instance
before attempting magic methods on the proxy. Write contexts (BP_VAR_W/RW)
are excluded because read_property with those types is used as a fallback
from get_property_ptr_ptr for reference operations involving __get.

Closes phpGH-21478
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Property access on lazy proxy may invoke magic method despite real instance guards

1 participant