1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Revert "Fix infinite recursion on deprecated attribute evaluation"

This reverts commit 272f7f75e2.

Reverts GH-17712 for the PHP-8.4 branch. This will be reapplied later
with a fix for GH-18463 (GH-18464).
This commit is contained in:
Ilija Tovilo
2025-04-30 20:52:56 +02:00
committed by Saki Takamachi
parent 4621423e5e
commit bbd9732f83
8 changed files with 9 additions and 73 deletions

View File

@@ -1,28 +0,0 @@
--TEST--
GH-17711: Infinite recursion through deprecated class constants self-referencing through deprecation message
--FILE--
<?php
class C {
#[\Deprecated(self::C)]
const C = TEST;
}
const TEST = 'Message';
var_dump(C::C);
class D {
#[\Deprecated(Alias::C)]
const C = 'test';
}
class_alias('D', 'Alias');
var_dump(D::C);
?>
--EXPECTF--
Deprecated: Constant C::C is deprecated, Message in %s on line %d
string(7) "Message"
Deprecated: Constant D::C is deprecated, test in %s on line %d
string(4) "test"

View File

@@ -1439,7 +1439,7 @@ ZEND_API HashTable *zend_separate_class_constants_table(zend_class_entry *class_
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&class_type->constants_table, key, c) {
if (c->ce == class_type) {
if (Z_TYPE(c->value) == IS_CONSTANT_AST || (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED)) {
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;

View File

@@ -8822,10 +8822,6 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as
if (deprecated) {
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED;
/* For deprecated constants, we need to flag the zval for recursion
* detection. Make sure the zval is separated out of shm. */
ce->ce_flags |= ZEND_ACC_HAS_AST_CONSTANTS;
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
}
}
}

View File

@@ -353,10 +353,8 @@ ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *
}
if (UNEXPECTED(ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED)) {
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0 && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
goto failure;
}

View File

@@ -27,17 +27,6 @@
#define CONST_NO_FILE_CACHE (1<<1) /* Can't be saved in file cache */
#define CONST_DEPRECATED (1<<2) /* Deprecated */
#define CONST_OWNED (1<<3) /* constant should be destroyed together with class */
#define CONST_RECURSIVE (1<<4) /* Recursion protection for constant evaluation */
#define CONST_IS_RECURSIVE(c) (Z_CONSTANT_FLAGS((c)->value) & CONST_RECURSIVE)
#define CONST_PROTECT_RECURSION(c) \
do { \
Z_CONSTANT_FLAGS((c)->value) |= CONST_RECURSIVE; \
} while (0)
#define CONST_UNPROTECT_RECURSION(c) \
do { \
Z_CONSTANT_FLAGS((c)->value) &= ~CONST_RECURSIVE; \
} while (0)
#define PHP_USER_CONSTANT 0x7fffff /* a constant defined in user space */

View File

@@ -6094,10 +6094,8 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
}
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if (UNEXPECTED(is_constant_deprecated)) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));

24
Zend/zend_vm_execute.h generated
View File

@@ -7615,10 +7615,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
}
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if (UNEXPECTED(is_constant_deprecated)) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -8777,10 +8775,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
}
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if (UNEXPECTED(is_constant_deprecated)) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -25878,10 +25874,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
}
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if (UNEXPECTED(is_constant_deprecated)) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -26449,10 +26443,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
}
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if (UNEXPECTED(is_constant_deprecated)) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -35290,10 +35282,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
}
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if (UNEXPECTED(is_constant_deprecated)) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -35651,10 +35641,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
}
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
CONST_PROTECT_RECURSION(c);
if (UNEXPECTED(is_constant_deprecated)) {
zend_deprecated_class_constant(c, constant_name);
CONST_UNPROTECT_RECURSION(c);
if (EG(exception)) {
ZVAL_UNDEF(EX_VAR(opline->result.var));

View File

@@ -3800,11 +3800,6 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) {
val = &c->value;
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
/* For deprecated constants, we need to flag the zval for recursion
* detection. Make sure the zval is separated out of shm. */
if (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED) {
ok = false;
}
if (EXPECTED(zend_update_class_constant(c, key, c->ce) == SUCCESS)) {
was_changed = changed = true;
} else {