Skip to content

Commit ac2734b

Browse files
committed
Fix persisting of inherited class constants
Class constants are inherited to user classes without cloning. Thus, internal class constants should not be persisted at all. Simply keep pointing to the internal class constant. Fixes GH-14109
1 parent 8c8287a commit ac2734b

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

ext/opcache/zend_persist.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,12 +806,16 @@ static zend_property_info *zend_persist_property_info(zend_property_info *prop)
806806

807807
static void zend_persist_class_constant(zval *zv)
808808
{
809-
zend_class_constant *c = zend_shared_alloc_get_xlat_entry(Z_PTR_P(zv));
809+
zend_class_constant *orig_c = Z_PTR_P(zv);
810+
zend_class_constant *c = zend_shared_alloc_get_xlat_entry(orig_c);
810811
zend_class_entry *ce;
811812

812813
if (c) {
813814
Z_PTR_P(zv) = c;
814815
return;
816+
} else if ((orig_c->ce->ce_flags & ZEND_ACC_IMMUTABLE) || orig_c->ce->type == ZEND_INTERNAL_CLASS) {
817+
/* Class constant comes from a different file in shm or internal class, keep existing pointer. */
818+
return;
815819
} else if (!ZCG(current_persistent_script)->corrupted
816820
&& zend_accel_in_shm(Z_PTR_P(zv))) {
817821
return;

ext/opcache/zend_persist_calc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ static void zend_persist_class_constant_calc(zval *zv)
386386
zend_class_constant *c = Z_PTR_P(zv);
387387

388388
if (!zend_shared_alloc_get_xlat_entry(c)) {
389+
if ((c->ce->ce_flags & ZEND_ACC_IMMUTABLE) || c->ce->type == ZEND_INTERNAL_CLASS) {
390+
/* Class constant comes from a different file in shm or internal class, keep existing pointer. */
391+
return;
392+
}
389393
if (!ZCG(current_persistent_script)->corrupted
390394
&& zend_accel_in_shm(Z_PTR_P(zv))) {
391395
return;

ext/zend_test/tests/gh14109.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
GH-14109: User class extending internal class with attributes
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
class Test extends ZendAttributeTest {}
8+
foreach ((new ReflectionClassConstant(Test::class, 'TEST_CONST'))->getAttributes() as $attribute) {
9+
var_dump($attribute->newInstance());
10+
}
11+
?>
12+
--EXPECTF--
13+
object(ZendTestRepeatableAttribute)#%d (0) {
14+
}
15+
object(ZendTestRepeatableAttribute)#%d (0) {
16+
}

0 commit comments

Comments
 (0)