Skip to content

Commit 04522cd

Browse files
Merge branch 'PHP-8.4'
* PHP-8.4: Reapply GH-17712 with a fix for internal class constants (#18464)
2 parents 7e956f8 + cd751f9 commit 04522cd

File tree

5 files changed

+80
-16
lines changed

5 files changed

+80
-16
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ PHP NEWS
4949
. Added get_error_handler(), get_exception_handler() functions. (Arnaud)
5050
. Fixed bug GH-15753 and GH-16198 (Bind traits before parent class). (ilutov)
5151
. Added support for casts in constant expressions. (nielsdos)
52+
. Fixed bugs GH-17711 and GH-18022 (Infinite recursion on deprecated attribute
53+
evaluation) and GH-18464 (Recursion protection for deprecation constants not
54+
released on bailout). (DanielEScherzer and ilutov)
5255

5356
- Curl:
5457
. Added curl_multi_get_handles(). (timwolla)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-18463: Recursion protection should not be applied to internal class constants
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
function handler($errno, $errstr, $errfile, $errline) {
9+
echo "$errstr in $errfile on line $errline\n";
10+
eval('class string {}');
11+
}
12+
13+
set_error_handler('handler');
14+
15+
var_dump(_ZendTestClass::ZEND_TEST_DEPRECATED);
16+
?>
17+
--EXPECTF--
18+
Constant _ZendTestClass::ZEND_TEST_DEPRECATED is deprecated in %s on line %d
19+
20+
Fatal error: Cannot use "string" as a class name as it is reserved in %s(%d) : eval()'d code on line %d

Zend/zend_constants.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,15 @@ ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *
373373

374374
if (UNEXPECTED(ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED)) {
375375
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0 && !CONST_IS_RECURSIVE(c)) {
376+
if (c->ce->type == ZEND_USER_CLASS) {
377+
/* Recursion protection only applied to user constants, GH-18463 */
378+
CONST_PROTECT_RECURSION(c);
379+
}
376380
CONST_PROTECT_RECURSION(c);
377381
zend_deprecated_class_constant(c, constant_name);
378-
CONST_UNPROTECT_RECURSION(c);
382+
if (c->ce->type == ZEND_USER_CLASS) {
383+
CONST_UNPROTECT_RECURSION(c);
384+
}
379385
if (EG(exception)) {
380386
goto failure;
381387
}

Zend/zend_vm_def.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6156,10 +6156,15 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
61566156
}
61576157

61586158
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
6159-
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
6160-
CONST_PROTECT_RECURSION(c);
6159+
if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
6160+
if (c->ce->type == ZEND_USER_CLASS) {
6161+
/* Recursion protection only applied to user constants, GH-18463 */
6162+
CONST_PROTECT_RECURSION(c);
6163+
}
61616164
zend_deprecated_class_constant(c, constant_name);
6162-
CONST_UNPROTECT_RECURSION(c);
6165+
if (c->ce->type == ZEND_USER_CLASS) {
6166+
CONST_UNPROTECT_RECURSION(c);
6167+
}
61636168

61646169
if (EG(exception)) {
61656170
ZVAL_UNDEF(EX_VAR(opline->result.var));

Zend/zend_vm_execute.h

Lines changed: 42 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)