Skip to content

Commit 27304b6

Browse files
committed
Fixes
1 parent cb99afd commit 27304b6

File tree

4 files changed

+25
-8
lines changed

4 files changed

+25
-8
lines changed

Zend/zend_inheritance.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,10 +2267,15 @@ ZEND_API void zend_class_use_traits(zend_class_entry *class_entry, int num_trait
22672267
}
22682268

22692269
traits = safe_emalloc(num_traits, sizeof(zend_class_entry *), 0);
2270+
class_entry->trait_names = safe_pemalloc(num_traits, sizeof(zend_class_name), 0, 1);
2271+
class_entry->num_traits = num_traits;
22702272

22712273
va_start(trait_list, num_traits);
22722274
for (int i = 0; i < num_traits; i++) {
22732275
trait_entry = va_arg(trait_list, zend_class_entry *);
2276+
class_entry->trait_names[i].name = zend_string_copy(trait_entry->name);
2277+
class_entry->trait_names[i].lc_name = zend_string_tolower_ex(zend_string_copy(trait_entry->name), 1);
2278+
22742279
if (UNEXPECTED(!(trait_entry->ce_flags & ZEND_ACC_TRAIT))) {
22752280
efree(traits);
22762281
zend_error_noreturn(E_ERROR, "Class %s cannot use %s - it is not a trait",
@@ -2457,7 +2462,11 @@ static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_
24572462
}
24582463
}
24592464

2460-
if (UNEXPECTED(fn->type == ZEND_INTERNAL_FUNCTION)) {
2465+
if (ce->type == ZEND_INTERNAL_CLASS) {
2466+
ZEND_ASSERT(fn->type == ZEND_INTERNAL_FUNCTION);
2467+
new_fn = (zend_function*)(uintptr_t)malloc(sizeof(zend_internal_function));
2468+
memcpy(new_fn, fn, sizeof(zend_internal_function));
2469+
} else if (UNEXPECTED(fn->type == ZEND_INTERNAL_FUNCTION)) {
24612470
new_fn = zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
24622471
memcpy(new_fn, fn, sizeof(zend_internal_function));
24632472
new_fn->common.fn_flags |= ZEND_ACC_ARENA_ALLOCATED;
@@ -2878,7 +2887,11 @@ static void zend_do_traits_constant_binding(zend_class_entry *ce, zend_class_ent
28782887
if (do_trait_constant_check(ce, constant, constant_name, traits, i)) {
28792888
zend_class_constant *ct = NULL;
28802889

2881-
ct = zend_arena_alloc(&CG(arena),sizeof(zend_class_constant));
2890+
if (ce->type == ZEND_INTERNAL_CLASS) {
2891+
ct = malloc(sizeof(zend_class_constant));
2892+
} else {
2893+
ct = zend_arena_alloc(&CG(arena),sizeof(zend_class_constant));
2894+
}
28822895
memcpy(ct, constant, sizeof(zend_class_constant));
28832896
constant = ct;
28842897

Zend/zend_opcode.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ ZEND_API void destroy_zend_class(zval *zv)
486486
zend_string_release_ex(ce->name, 1);
487487

488488
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
489-
if (fn->common.scope == ce) {
489+
if (fn->common.scope == ce && !(fn->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
490490
zend_free_internal_arg_info(&fn->internal_function, true);
491491

492492
if (fn->common.attributes) {
@@ -536,6 +536,13 @@ ZEND_API void destroy_zend_class(zval *zv)
536536
if (ce->attributes) {
537537
zend_hash_release(ce->attributes);
538538
}
539+
if (ce->num_traits > 0) {
540+
for (uint32_t i = 0; i < ce->num_traits; i++) {
541+
zend_string_release(ce->trait_names[i].name);
542+
zend_string_release(ce->trait_names[i].lc_name);
543+
}
544+
free(ce->trait_names);
545+
}
539546
free(ce);
540547
break;
541548
}

ext/zend_test/test.stub.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ trait _ZendTestTraitForInternalClass
4141

4242
public int $traitProp = 456;
4343

44-
public function traitMethod(): int
45-
{
46-
return 789;
47-
}
44+
public function traitMethod(): int {}
4845
}
4946

5047
class _ZendTestClassWithTrait

ext/zend_test/test_arginfo.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)