Skip to content

Commit c1959e6

Browse files
committed
Fix preloading of enums
We should not store constants that resolve to objects.
1 parent 703e92c commit c1959e6

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

ext/opcache/ZendAccelerator.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3711,6 +3711,19 @@ static void get_unlinked_dependency(zend_class_entry *ce, const char **kind, con
37113711
}
37123712
}
37133713

3714+
static zend_result preload_update_constant(zval *val, zend_class_entry *scope)
3715+
{
3716+
zval tmp;
3717+
ZVAL_COPY(&tmp, val);
3718+
if (zval_update_constant_ex(&tmp, scope) == FAILURE || Z_TYPE(tmp) == IS_OBJECT) {
3719+
zval_ptr_dtor(&tmp);
3720+
return FAILURE;
3721+
}
3722+
zval_ptr_dtor_nogc(val);
3723+
ZVAL_COPY_VALUE(val, &tmp);
3724+
return SUCCESS;
3725+
}
3726+
37143727
static bool preload_try_resolve_constants(zend_class_entry *ce)
37153728
{
37163729
bool ok, changed, was_changed = 0;
@@ -3724,7 +3737,7 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
37243737
ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) {
37253738
val = &c->value;
37263739
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
3727-
if (EXPECTED(zval_update_constant_ex(val, c->ce) == SUCCESS)) {
3740+
if (EXPECTED(preload_update_constant(val, c->ce) == SUCCESS)) {
37283741
was_changed = changed = 1;
37293742
} else {
37303743
ok = 0;
@@ -3742,7 +3755,7 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
37423755
val = &ce->default_properties_table[i];
37433756
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
37443757
zend_property_info *prop = ce->properties_info_table[i];
3745-
if (UNEXPECTED(zval_update_constant_ex(val, prop->ce) != SUCCESS)) {
3758+
if (UNEXPECTED(preload_update_constant(val, prop->ce) != SUCCESS)) {
37463759
resolved = ok = 0;
37473760
}
37483761
}
@@ -3758,7 +3771,7 @@ static bool preload_try_resolve_constants(zend_class_entry *ce)
37583771
val = ce->default_static_members_table + ce->default_static_members_count - 1;
37593772
while (count) {
37603773
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
3761-
if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) {
3774+
if (UNEXPECTED(preload_update_constant(val, ce) != SUCCESS)) {
37623775
resolved = ok = 0;
37633776
}
37643777
}

ext/opcache/tests/preload_enum.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
enum MyEnum {
4+
case Foo;
5+
case Bar;
6+
}

ext/opcache/tests/preload_enum.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Enum preloading
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.optimization_level=-1
9+
opcache.preload={PWD}/preload_enum.inc
10+
--SKIPIF--
11+
<?php
12+
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
13+
--FILE--
14+
<?php
15+
16+
var_dump(MyEnum::Foo);
17+
18+
?>
19+
--EXPECT--
20+
enum(MyEnum::Foo)

0 commit comments

Comments
 (0)