mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Fix preloading of constants containing enums
Fixes GH-8133
This commit is contained in:
parent
e9b9fec2b2
commit
4397811db2
2
NEWS
2
NEWS
@ -5,6 +5,8 @@ PHP NEWS
|
||||
- Core:
|
||||
. Fixed bug GH-8310 (Registry settings are no longer recognized). (cmb)
|
||||
. Fixed potential race condition during resource ID allocation. (ryancaicse)
|
||||
. Fixed bug GH-8133 (Preloading of constants containing arrays with enums
|
||||
segfaults). (ilutov)
|
||||
|
||||
- Date:
|
||||
. Fixed bug GH-7752 (DateTimeZone::getTransitions() returns insufficient
|
||||
|
@ -750,6 +750,12 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast
|
||||
break;
|
||||
case ZEND_AST_CONST_ENUM_INIT:
|
||||
{
|
||||
// Preloading will attempt to resolve constants but objects can't be stored in shm
|
||||
// Aborting here to store the const AST instead
|
||||
if (CG(in_compilation)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zend_ast *class_name_ast = ast->child[0];
|
||||
zend_string *class_name = zend_ast_get_str(class_name_ast);
|
||||
|
||||
@ -762,13 +768,6 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast
|
||||
: NULL;
|
||||
|
||||
zend_class_entry *ce = zend_lookup_class(class_name);
|
||||
if (!ce) {
|
||||
/* Class may not be available when resolving constants on a dynamically
|
||||
* declared enum during preloading. */
|
||||
ZEND_ASSERT(CG(compiler_options) & ZEND_COMPILE_PRELOAD);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zend_enum_new(result, ce, case_name, case_value_zv);
|
||||
break;
|
||||
}
|
||||
|
@ -3725,19 +3725,6 @@ static zend_result preload_resolve_deps(preload_error *error, const zend_class_e
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static zend_result preload_update_constant(zval *val, zend_class_entry *scope)
|
||||
{
|
||||
zval tmp;
|
||||
ZVAL_COPY(&tmp, val);
|
||||
if (zval_update_constant_ex(&tmp, scope) == FAILURE || Z_TYPE(tmp) == IS_OBJECT) {
|
||||
zval_ptr_dtor(&tmp);
|
||||
return FAILURE;
|
||||
}
|
||||
zval_ptr_dtor_nogc(val);
|
||||
ZVAL_COPY_VALUE(val, &tmp);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static bool preload_try_resolve_constants(zend_class_entry *ce)
|
||||
{
|
||||
bool ok, changed, was_changed = 0;
|
||||
@ -3751,7 +3738,7 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
|
||||
ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) {
|
||||
val = &c->value;
|
||||
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
|
||||
if (EXPECTED(preload_update_constant(val, c->ce) == SUCCESS)) {
|
||||
if (EXPECTED(zval_update_constant_ex(val, c->ce) == SUCCESS)) {
|
||||
was_changed = changed = 1;
|
||||
} else {
|
||||
ok = 0;
|
||||
@ -3769,7 +3756,7 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
|
||||
val = &ce->default_properties_table[i];
|
||||
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
|
||||
zend_property_info *prop = ce->properties_info_table[i];
|
||||
if (UNEXPECTED(preload_update_constant(val, prop->ce) != SUCCESS)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(val, prop->ce) != SUCCESS)) {
|
||||
resolved = ok = 0;
|
||||
}
|
||||
}
|
||||
@ -3785,7 +3772,7 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
|
||||
val = ce->default_static_members_table + ce->default_static_members_count - 1;
|
||||
while (count) {
|
||||
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(preload_update_constant(val, ce) != SUCCESS)) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) {
|
||||
resolved = ok = 0;
|
||||
}
|
||||
}
|
||||
|
12
ext/opcache/tests/gh8133.inc
Normal file
12
ext/opcache/tests/gh8133.inc
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
enum Foo
|
||||
{
|
||||
case Bar;
|
||||
case Baz;
|
||||
const CASES = [Foo::Bar, Foo::Baz];
|
||||
}
|
||||
|
||||
class Qux {
|
||||
const CASES = [Foo::Bar, Foo::Baz];
|
||||
}
|
33
ext/opcache/tests/gh8133.phpt
Normal file
33
ext/opcache/tests/gh8133.phpt
Normal file
@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Enum preloading
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.optimization_level=-1
|
||||
opcache.preload={PWD}/gh8133.inc
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(Foo::CASES);
|
||||
var_dump(Qux::CASES);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
[0]=>
|
||||
enum(Foo::Bar)
|
||||
[1]=>
|
||||
enum(Foo::Baz)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
enum(Foo::Bar)
|
||||
[1]=>
|
||||
enum(Foo::Baz)
|
||||
}
|
Loading…
Reference in New Issue
Block a user