Fix GH-10914: OPCache with Enum and Callback functions results in segmentation fault

See linked issue for analysis.

Closes GH-11675.
This commit is contained in:
Niels Dossche 2023-07-11 16:39:25 +02:00
parent 6b87e08b82
commit bc42179133
4 changed files with 37 additions and 2 deletions

4
NEWS
View file

@ -41,6 +41,10 @@ PHP NEWS
. Fix GH-11300 (license issue: restricted unicode license headers). . Fix GH-11300 (license issue: restricted unicode license headers).
(nielsdos) (nielsdos)
- Opcache:
. Fixed bug GH-10914 (OPCache with Enum and Callback functions results in
segmentation fault). (nielsdos)
- PCNTL: - PCNTL:
. Fixed bug GH-11498 (SIGCHLD is not always returned from proc_open). . Fixed bug GH-11498 (SIGCHLD is not always returned from proc_open).
(nielsdos) (nielsdos)

View file

@ -0,0 +1,26 @@
--TEST--
GH-10914 (OPCache with Enum and Callback functions results in segmentation fault)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.protect_memory=1
opcache.preload={PWD}/preload_gh10914.inc
--EXTENSIONS--
opcache
--SKIPIF--
<?php
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
?>
--FILE--
<?php
$x = new ReflectionEnum(ExampleEnum::class);
var_dump($x->getCases()[0]->getValue());
var_dump($x->getCases()[0]->getBackingValue());
var_dump($x->getCase('FIRST')->getValue());
var_dump($x->getCase('FIRST')->getBackingValue());
?>
--EXPECT--
enum(ExampleEnum::FIRST)
string(4) "AAAb"
enum(ExampleEnum::FIRST)
string(4) "AAAb"

View file

@ -0,0 +1,5 @@
<?php
enum ExampleEnum: string
{
case FIRST = "AAA"."b";
}

View file

@ -6798,7 +6798,7 @@ ZEND_METHOD(ReflectionEnum, getCase)
GET_REFLECTION_OBJECT_PTR(ce); GET_REFLECTION_OBJECT_PTR(ce);
zend_class_constant *constant = zend_hash_find_ptr(&ce->constants_table, name); zend_class_constant *constant = zend_hash_find_ptr(CE_CONSTANTS_TABLE(ce), name);
if (constant == NULL) { if (constant == NULL) {
zend_throw_exception_ex(reflection_exception_ptr, 0, "Case %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); zend_throw_exception_ex(reflection_exception_ptr, 0, "Case %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name));
RETURN_THROWS(); RETURN_THROWS();
@ -6825,7 +6825,7 @@ ZEND_METHOD(ReflectionEnum, getCases)
GET_REFLECTION_OBJECT_PTR(ce); GET_REFLECTION_OBJECT_PTR(ce);
array_init(return_value); array_init(return_value);
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, name, constant) { ZEND_HASH_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), name, constant) {
if (ZEND_CLASS_CONST_FLAGS(constant) & ZEND_CLASS_CONST_IS_CASE) { if (ZEND_CLASS_CONST_FLAGS(constant) & ZEND_CLASS_CONST_IS_CASE) {
zval class_const; zval class_const;
reflection_enum_case_factory(ce, name, constant, &class_const); reflection_enum_case_factory(ce, name, constant, &class_const);