]> granicus.if.org Git - php/commitdiff
Fixed bug #79548
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 4 May 2020 14:27:45 +0000 (16:27 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 4 May 2020 14:27:45 +0000 (16:27 +0200)
When duplicating user functions with static variables, make sure
that we init a new map ptr slot for the static variables.

Zend/zend_inheritance.c
ext/opcache/tests/preload_static_var_inheritance.inc [new file with mode: 0644]
ext/opcache/tests/preload_static_var_inheritance.phpt [new file with mode: 0644]

index 6bd35a6bb788d5b962ed8feda5ba67248ea04a03..e7dcf54e0d571c27dec63902a66e87c155ea5e88 100644 (file)
@@ -86,7 +86,14 @@ static zend_function *zend_duplicate_user_function(zend_function *func) /* {{{ *
        if (!(GC_FLAGS(new_function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
                GC_ADDREF(new_function->op_array.static_variables);
        }
-       ZEND_MAP_PTR_INIT(new_function->op_array.static_variables_ptr, &new_function->op_array.static_variables);
+
+       if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) {
+               ZEND_ASSERT(new_function->op_array.fn_flags & ZEND_ACC_PRELOADED);
+               ZEND_MAP_PTR_NEW(new_function->op_array.static_variables_ptr);
+       } else {
+               ZEND_MAP_PTR_INIT(new_function->op_array.static_variables_ptr, &new_function->op_array.static_variables);
+       }
+
        return new_function;
 }
 /* }}} */
diff --git a/ext/opcache/tests/preload_static_var_inheritance.inc b/ext/opcache/tests/preload_static_var_inheritance.inc
new file mode 100644 (file)
index 0000000..56ed65c
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+class A {
+    public function test() {
+        static $foo;
+    }
+}
+
+class B extends A {}
diff --git a/ext/opcache/tests/preload_static_var_inheritance.phpt b/ext/opcache/tests/preload_static_var_inheritance.phpt
new file mode 100644 (file)
index 0000000..dd5e430
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Bug #79548: Preloading segfault with inherited method using static variable
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.preload={PWD}/preload_static_var_inheritance.inc
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
+?>
+--FILE--
+<?php
+var_dump((new B)->test());
+?>
+--EXPECT--
+NULL