Skip to content

Commit 2d18803

Browse files
committed
Fix another indirect recursive case
1 parent da6767d commit 2d18803

File tree

4 files changed

+19
-9
lines changed

4 files changed

+19
-9
lines changed

Zend/tests/attributes/deprecated/class_constants/gh17711.phpt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,26 @@ GH-17711: Infinite recursion through deprecated class constants self-referencing
33
--FILE--
44
<?php
55

6-
const TEST = 'Message';
7-
86
class C {
97
#[\Deprecated(self::C)]
108
const C = TEST;
119
}
1210

11+
const TEST = 'Message';
1312
var_dump(C::C);
1413

14+
class D {
15+
#[\Deprecated(Alias::C)]
16+
const C = 'test';
17+
}
18+
19+
class_alias('D', 'Alias');
20+
var_dump(D::C);
21+
1522
?>
1623
--EXPECTF--
1724
Deprecated: Constant C::C is deprecated, Message in %s on line %d
1825
string(7) "Message"
26+
27+
Deprecated: Constant D::C is deprecated, test in %s on line %d
28+
string(4) "test"

Zend/zend_API.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,7 @@ ZEND_API HashTable *zend_separate_class_constants_table(zend_class_entry *class_
14391439

14401440
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&class_type->constants_table, key, c) {
14411441
if (c->ce == class_type) {
1442-
if (Z_TYPE(c->value) == IS_CONSTANT_AST) {
1442+
if (Z_TYPE(c->value) == IS_CONSTANT_AST || (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED)) {
14431443
new_c = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant));
14441444
memcpy(new_c, c, sizeof(zend_class_constant));
14451445
c = new_c;

Zend/zend_compile.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8822,6 +8822,10 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as
88228822

88238823
if (deprecated) {
88248824
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED;
8825+
/* For deprecated constants, we need to flag the zval for recursion
8826+
* detection. Make sure the zval is separated out of shm. */
8827+
ce->ce_flags |= ZEND_ACC_HAS_AST_CONSTANTS;
8828+
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
88258829
}
88268830
}
88278831
}

Zend/zend_constants.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,11 @@
3232
#define CONST_IS_RECURSIVE(c) (Z_CONSTANT_FLAGS((c)->value) & CONST_RECURSIVE)
3333
#define CONST_PROTECT_RECURSION(c) \
3434
do { \
35-
if (Z_TYPE((c)->value) == IS_CONSTANT_AST) { \
36-
Z_CONSTANT_FLAGS((c)->value) |= CONST_RECURSIVE; \
37-
} \
35+
Z_CONSTANT_FLAGS((c)->value) |= CONST_RECURSIVE; \
3836
} while (0)
3937
#define CONST_UNPROTECT_RECURSION(c) \
4038
do { \
41-
if (Z_TYPE((c)->value) == IS_CONSTANT_AST) { \
42-
Z_CONSTANT_FLAGS((c)->value) &= ~CONST_RECURSIVE; \
43-
} \
39+
Z_CONSTANT_FLAGS((c)->value) &= ~CONST_RECURSIVE; \
4440
} while (0)
4541

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

0 commit comments

Comments
 (0)