Skip to content

Fix GH-23842: skipLazyInitialization() copies unresolved constant defaults - #23843

Open
lazerg wants to merge 2 commits into
php:PHP-8.4from
lazerg:fix/gh-23842-skip-lazy-init-opcache-default
Open

lazerg wants to merge 2 commits into
php:PHP-8.4from
lazerg:fix/gh-23842-skip-lazy-init-opcache-default

Conversation

@lazerg

@lazerg lazerg commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Fixes GH-23842.

skipLazyInitialization() reads the property default straight out of ce->default_properties_table. Under shared-memory opcache the class entry is immutable and a default that references a class constant stays an unresolved AST there; the resolved value lives in the class's mutable data. So the method copied an IS_CONSTANT_AST zval into the object slot, and the property then held something that is not a valid value of its declared type. var_dump() on it prints UNKNOWN:0, and a typed return over it throws a TypeError.

CE_DEFAULT_PROPERTIES_TABLE() picks the mutable table when there is one, which is what the rest of the lazy object code already does in zend_lazy_object_mark_as_initialized() and zend_lazy_object_init(). property_get_default() still reads the raw field, but getDefaultValue() resolves the AST afterwards, so it is not affected.

The diagnosis and the one-line patch are DirkTrunkstar's, from the issue.

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.

1 participant