Fix registration of internal readonly child classes (#15459)

Currently, internal classes are registered with the following code:

INIT_CLASS_ENTRY(ce, "InternalClass", class_InternalClass_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
class_entry->ce_flags |= ...;

This has worked well so far, except if InternalClass is readonly. It is because some inheritance checks are run by zend_register_internal_class_ex before ZEND_ACC_READONLY_CLASS is added to ce_flags.

The issue is fixed by adding a zend_register_internal_class_with_flags() zend API function that stubs can use from now on. This function makes sure to add the flags before running any checks. Since the new API is not available in lower PHP versions, gen_stub.php has to keep support for the existing API for PHP 8.3 and below.
This commit is contained in:
Máté Kocsis 2024-08-24 12:36:54 +02:00 committed by GitHub
parent 6351468a5e
commit 8d12f666ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
96 changed files with 405 additions and 446 deletions

View file

@ -3493,9 +3493,16 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
*/
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce) /* {{{ */
{
zend_class_entry *register_class;
return zend_register_internal_class_with_flags(class_entry, parent_ce, 0);
}
/* }}} */
register_class = zend_register_internal_class(class_entry);
ZEND_API zend_class_entry *zend_register_internal_class_with_flags(
zend_class_entry *class_entry,
zend_class_entry *parent_ce,
uint32_t ce_flags
) {
zend_class_entry *register_class = do_register_internal_class(class_entry, ce_flags);
if (parent_ce) {
zend_do_inheritance(register_class, parent_ce);
@ -3504,7 +3511,6 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *cla
return register_class;
}
/* }}} */
ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...) /* {{{ */
{