Skip to content

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

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

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.

@ndossche ndossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, but note I will add the issue's OP as first author

@ndossche ndossche closed this in e0eea65 Sep 29, 2026
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.

2 participants