diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 4d73dd003a31..a4c759add64b 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2847,6 +2847,7 @@ static void zend_do_traits_constant_binding(zend_class_entry *ce, zend_class_ent constant->ce = ce; Z_TRY_ADDREF(constant->value); + zend_type_copy_ctor(&constant->type, /* use_arena */ true, /* persistent */ false); constant->doc_comment = constant->doc_comment ? zend_string_copy(constant->doc_comment) : NULL; if (constant->attributes && (!(GC_FLAGS(constant->attributes) & IS_ARRAY_IMMUTABLE))) { GC_ADDREF(constant->attributes); @@ -3489,6 +3490,7 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce) Z_PTR(p->val) = new_c; memcpy(new_c, c, sizeof(zend_class_constant)); new_c->ce = ce; + zend_type_copy_ctor(&new_c->type, /* use_arena */ true, /* persistent */ false); } } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 317f68b486bb..4edd1fbc7cb9 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -421,6 +421,9 @@ ZEND_API void destroy_zend_class(zval *zv) zend_hash_release(c->attributes); } } + if (c->ce == ce) { + zend_type_release(c->type, /* persistent */ 0); + } } ZEND_HASH_FOREACH_END(); } zend_hash_destroy(&ce->constants_table); diff --git a/ext/opcache/tests/gh25149.phpt b/ext/opcache/tests/gh25149.phpt new file mode 100644 index 000000000000..657dc193d1a6 --- /dev/null +++ b/ext/opcache/tests/gh25149.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-25149 (Memory leak of class constant type names in classes not cached by opcache) +--EXTENSIONS-- +opcache +--INI-- +opcache.enable_cli=1 +--FILE-- + +--EXPECT-- +NULL +NULL +NULL +NULL +NULL +NULL