Skip to content

Commit f080a90

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Fix memory leak
2 parents 9149d16 + b1b79c7 commit f080a90

File tree

4 files changed

+19
-2
lines changed

4 files changed

+19
-2
lines changed

Zend/tests/class_constants_006.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Ownership of constant expression inhereted from interface should be transfered to class
3+
--FILE--
4+
<?php
5+
interface I {
6+
const X2 = 'X' . self::Y2;
7+
const Y2 = 'Y';
8+
}
9+
eval('class B implements I{}');
10+
var_dump(B::X2);
11+
?>
12+
--EXPECT--
13+
string(2) "XY"

Zend/zend_constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define CONST_PERSISTENT (1<<0) /* Persistent */
2727
#define CONST_NO_FILE_CACHE (1<<1) /* Can't be saved in file cache */
2828
#define CONST_DEPRECATED (1<<2) /* Deprecated */
29+
#define CONST_OWNED (1<<3) /* constant should be destroyed together with class */
2930

3031
#define PHP_USER_CONSTANT 0x7fffff /* a constant defined in user space */
3132

Zend/zend_inheritance.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "zend_exceptions.h"
2929
#include "zend_enum.h"
3030
#include "zend_attributes.h"
31+
#include "zend_constants.h"
3132

3233
ZEND_API zend_class_entry* (*zend_inheritance_cache_get)(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces) = NULL;
3334
ZEND_API zend_class_entry* (*zend_inheritance_cache_add)(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies) = NULL;
@@ -1632,6 +1633,7 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c,
16321633
ct = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant));
16331634
memcpy(ct, c, sizeof(zend_class_constant));
16341635
c = ct;
1636+
Z_CONSTANT_FLAGS(c->value) |= CONST_OWNED;
16351637
}
16361638
}
16371639
if (ce->type & ZEND_INTERNAL_CLASS) {

Zend/zend_opcode.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "zend_extensions.h"
2727
#include "zend_API.h"
2828
#include "zend_sort.h"
29+
#include "zend_constants.h"
2930

3031
#include "zend_vm.h"
3132

@@ -255,7 +256,7 @@ ZEND_API void zend_cleanup_mutable_class_data(zend_class_entry *ce)
255256
zend_class_constant *c;
256257

257258
ZEND_HASH_MAP_FOREACH_PTR(constants_table, c) {
258-
if (c->ce == ce) {
259+
if (c->ce == ce || (Z_CONSTANT_FLAGS(c->value) & CONST_OWNED)) {
259260
zval_ptr_dtor_nogc(&c->value);
260261
}
261262
} ZEND_HASH_FOREACH_END();
@@ -387,7 +388,7 @@ ZEND_API void destroy_zend_class(zval *zv)
387388
zend_class_constant *c;
388389

389390
ZEND_HASH_MAP_FOREACH_PTR(&ce->constants_table, c) {
390-
if (c->ce == ce) {
391+
if (c->ce == ce || (Z_CONSTANT_FLAGS(c->value) & CONST_OWNED)) {
391392
zval_ptr_dtor_nogc(&c->value);
392393
if (c->doc_comment) {
393394
zend_string_release_ex(c->doc_comment, 0);

0 commit comments

Comments
 (0)