diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-11-04 15:33:11 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-11-04 15:42:52 +0100 |
commit | 670fe594b9cb838ddc78b7da0dc8aa55f3eebf3f (patch) | |
tree | 84c24e70f5e50c7ee3c24ad4f5d64096639aa1bd | |
parent | b8f2531ff0ac6a5e7828debd56e8e37ee04a4d6a (diff) | |
download | php-git-670fe594b9cb838ddc78b7da0dc8aa55f3eebf3f.tar.gz |
Fix static variable in methods inheritance during preloading
This is now "bug compatible" with the normal behavior, and more
imporantly, does not crash :)
-rw-r--r-- | Zend/zend_inheritance.c | 16 | ||||
-rw-r--r-- | ext/opcache/tests/preload_method_static_vars.inc | 15 | ||||
-rw-r--r-- | ext/opcache/tests/preload_method_static_vars.phpt | 25 |
3 files changed, 49 insertions, 7 deletions
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index b0f4055be1..7401456d8f 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -90,13 +90,6 @@ static zend_function *zend_duplicate_user_function(zend_function *func) /* {{{ * new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array)); memcpy(new_function, func, sizeof(zend_op_array)); - if (ZEND_MAP_PTR_GET(func->op_array.static_variables_ptr)) { - /* See: Zend/tests/method_static_var.phpt */ - new_function->op_array.static_variables = ZEND_MAP_PTR_GET(func->op_array.static_variables_ptr); - } - if (!(GC_FLAGS(new_function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(new_function->op_array.static_variables); - } if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) { ZEND_ASSERT(new_function->op_array.fn_flags & ZEND_ACC_PRELOADED); @@ -105,6 +98,15 @@ static zend_function *zend_duplicate_user_function(zend_function *func) /* {{{ * ZEND_MAP_PTR_INIT(new_function->op_array.static_variables_ptr, &new_function->op_array.static_variables); } + HashTable *static_properties_ptr = ZEND_MAP_PTR_GET(func->op_array.static_variables_ptr); + if (static_properties_ptr) { + /* See: Zend/tests/method_static_var.phpt */ + ZEND_MAP_PTR_SET(new_function->op_array.static_variables_ptr, static_properties_ptr); + GC_TRY_ADDREF(static_properties_ptr); + } else { + GC_TRY_ADDREF(new_function->op_array.static_variables); + } + return new_function; } /* }}} */ diff --git a/ext/opcache/tests/preload_method_static_vars.inc b/ext/opcache/tests/preload_method_static_vars.inc new file mode 100644 index 0000000000..03d3c6cb6f --- /dev/null +++ b/ext/opcache/tests/preload_method_static_vars.inc @@ -0,0 +1,15 @@ +<?php +class Foo { + public static function test() { + static $i = 0; + var_dump(++$i); + } +} + + +Foo::test(); +eval("class Bar extends Foo {}"); // Avoid early binding. +Foo::test(); +Bar::test(); +Bar::test(); +echo "\n"; diff --git a/ext/opcache/tests/preload_method_static_vars.phpt b/ext/opcache/tests/preload_method_static_vars.phpt new file mode 100644 index 0000000000..f3d211793c --- /dev/null +++ b/ext/opcache/tests/preload_method_static_vars.phpt @@ -0,0 +1,25 @@ +--TEST-- +Preloading inherited method with separated static vars +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.preload={PWD}/preload_method_static_vars.inc +--SKIPIF-- +<?php +require_once('skipif.inc'); +if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows'); +?> +--FILE-- +<?php +Foo::test(); +Bar::test(); +?> +--EXPECT-- +int(1) +int(2) +int(2) +int(3) + +int(1) +int(1) |