Skip to content

Commit 9b61479

Browse files
committed
We don't need to dup zend_class_constant here.
quote why the internal class is still using duplication: ``` for internal classes, the zend_class_constant is malloc-ed. we need to free it. if (const->ce == ce) { zval_ptr_dtor(&const->value); free(const) } so, if two classes share one const, and it(parent class) was freed before, this read(in child class, const->ce) is invalid.. and destroy_zend_class is called via zend_hash_destroy(class_table). which is not in reverse order... so, parent classes are dtor first. if we want this work, we should change that order. ```
1 parent af255c6 commit 9b61479

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

Zend/zend_inheritance.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -724,15 +724,15 @@ static void do_inherit_class_constant(zend_string *name, zend_class_constant *pa
724724
if (Z_CONSTANT(parent_const->value)) {
725725
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
726726
}
727-
if (Z_REFCOUNTED(parent_const->value)) {
728-
Z_ADDREF(parent_const->value);
729-
}
730727
if (ce->type & ZEND_INTERNAL_CLASS) {
728+
if (Z_REFCOUNTED(parent_const->value)) {
729+
Z_ADDREF(parent_const->value);
730+
}
731731
c = pemalloc(sizeof(zend_class_constant), 1);
732+
memcpy(c, parent_const, sizeof(zend_class_constant));
732733
} else {
733-
c = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant));
734+
c = parent_const;
734735
}
735-
memcpy(c, parent_const, sizeof(zend_class_constant));
736736
_zend_hash_append_ptr(&ce->constants_table, name, c);
737737
}
738738
}
@@ -934,18 +934,18 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c,
934934
{
935935
if (do_inherit_constant_check(&ce->constants_table, c, name, iface)) {
936936
zend_class_constant *ct;
937-
if (Z_REFCOUNTED(c->value)) {
938-
Z_ADDREF(c->value);
939-
}
940937
if (Z_CONSTANT(c->value)) {
941938
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
942939
}
943940
if (ce->type & ZEND_INTERNAL_CLASS) {
941+
if (Z_REFCOUNTED(c->value)) {
942+
Z_ADDREF(c->value);
943+
}
944944
ct = pemalloc(sizeof(zend_class_constant), 1);
945+
memcpy(ct, c, sizeof(zend_class_constant));
945946
} else {
946-
ct = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant));
947+
ct = c;
947948
}
948-
memcpy(ct, c, sizeof(zend_class_constant));
949949
zend_hash_update_ptr(&ce->constants_table, name, ct);
950950
}
951951
}

Zend/zend_opcode.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,11 @@ ZEND_API void destroy_zend_class(zval *zv)
291291
zend_class_constant *c;
292292

293293
ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) {
294-
zval_ptr_dtor(&c->value);
295-
if (c->doc_comment && c->ce == ce) {
296-
zend_string_release(c->doc_comment);
294+
if (c->ce == ce) {
295+
zval_ptr_dtor(&c->value);
296+
if (c->doc_comment) {
297+
zend_string_release(c->doc_comment);
298+
}
297299
}
298300
} ZEND_HASH_FOREACH_END();
299301
zend_hash_destroy(&ce->constants_table);

0 commit comments

Comments
 (0)