diff --git a/Zend/tests/class_constant_inheritance_mutable_data.phpt b/Zend/tests/class_constant_inheritance_mutable_data.phpt new file mode 100644 index 0000000000000..02bef7f02392e --- /dev/null +++ b/Zend/tests/class_constant_inheritance_mutable_data.phpt @@ -0,0 +1,35 @@ +--TEST-- +Class constant inheritance with mutable data +--FILE-- + +--EXPECTF-- +object(B)#1 (0) { +} +string(2) "XY" +string(4) "X2Y2" + +Deprecated: Implicit conversion from float 1.5 to int loses precision in %s on line %d +int(0) +int(0) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 69da32d7e18f5..20f867ffbdf1a 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1323,9 +1323,14 @@ ZEND_API HashTable *zend_separate_class_constants_table(zend_class_entry *class_ ZEND_HASH_FOREACH_STR_KEY_PTR(&class_type->constants_table, key, c) { if (Z_TYPE(c->value) == IS_CONSTANT_AST) { - new_c = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant)); - memcpy(new_c, c, sizeof(zend_class_constant)); - c = new_c; + if (c->ce == class_type) { + new_c = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant)); + memcpy(new_c, c, sizeof(zend_class_constant)); + c = new_c; + } else { + c = zend_hash_find_ptr(CE_CONSTANTS_TABLE(c->ce), key); + ZEND_ASSERT(c); + } } Z_TRY_ADDREF(c->value); _zend_hash_append_ptr(constants_table, key, c); @@ -1409,8 +1414,18 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) / } else { constants_table = &class_type->constants_table; } - ZEND_HASH_FOREACH_PTR(constants_table, c) { + + zend_string *name; + ZEND_HASH_FOREACH_STR_KEY_VAL(constants_table, name, val) { + c = Z_PTR_P(val); if (Z_TYPE(c->value) == IS_CONSTANT_AST) { + if (c->ce != class_type) { + Z_PTR_P(val) = c = zend_hash_find_ptr(CE_CONSTANTS_TABLE(c->ce), name); + if (Z_TYPE(c->value) != IS_CONSTANT_AST) { + continue; + } + } + val = &c->value; if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) { return FAILURE;