Skip to content

Recursion protection for deprecation constants not released on bailout #18463

Open
@DanielEScherzer

Description

@DanielEScherzer

Description

The following code:

<?php

function handler($errno, $errstr, $errfile, $errline) {
	echo "$errstr in $errfile on line $errline\n";
	eval('class string {}');
}

set_error_handler( 'handler' );

var_dump( _ZendTestClass::ZEND_TEST_DEPRECATED );

Invoked with php --repeat 2 /var/www/html/test.php
Resulted in this output:

Executing for the first time...
Constant _ZendTestClass::ZEND_TEST_DEPRECATED is deprecated in /var/www/html/test.php on line 10

Fatal error: Cannot use "string" as a class name as it is reserved in /var/www/html/test.php(5) : eval()'d code on line 1
Finished execution, repeating...
int(42)

But I expected this output instead:

Executing for the first time...
Constant _ZendTestClass::ZEND_TEST_DEPRECATED is deprecated in /var/www/html/test.php on line 10

Fatal error: Cannot use "string" as a class name as it is reserved in /var/www/html/test.php(5) : eval()'d code on line 1
Finished execution, repeating...
Constant _ZendTestClass::ZEND_TEST_DEPRECATED is deprecated in /var/www/html/test.php on line 10

Fatal error: Cannot use "string" as a class name as it is reserved in /var/www/html/test.php(5) : eval()'d code on line 1

Caused by the recursion protection (CONST_RECURSIVE flag) not getting removed because the user handler triggers a bailout. Should only apply to internal constants because userland constants aren't in the persistent memory and so would get recreated on a new request anyway

Also affects non-class constants on master following #16952
Relates to #17712

PHP Version

PHP 8.4 @ e18498e
PHP master @ 26dbcb7

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions