]> granicus.if.org Git - php/commitdiff
Remove func copy optimization for private method with static vars
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 1 Oct 2019 10:58:26 +0000 (12:58 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 1 Oct 2019 11:04:06 +0000 (13:04 +0200)
Not NULLing the static_variables pointer for shadow methods during
static var shutdown would be a way to avoid this leak, but unless
there's evidence that inherited private methods with static vars are
actually a common use-case, I don't think we should keep this kind
of fragile edge-case optimization.

Fixes OSS-Fuzz #17875.

Zend/tests/static_variable_in_private_method.phpt [new file with mode: 0644]
Zend/zend_execute_API.c
Zend/zend_inheritance.c

diff --git a/Zend/tests/static_variable_in_private_method.phpt b/Zend/tests/static_variable_in_private_method.phpt
new file mode 100644 (file)
index 0000000..0aa04a0
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Inheritance of private method with static variable
+--FILE--
+<?php
+
+class A {
+    private function m() {
+        static $x;
+    }
+}
+class B extends A {}
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
index 3c78d2524d5060160125bee505d4746ff0e3fb8e..c2ab453485224dd582a1eaba5b15c9d59d611083 100644 (file)
@@ -302,7 +302,7 @@ void shutdown_executor(void) /* {{{ */
                        }
                        if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
                                zend_op_array *op_array;
-                                       ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
+                               ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
                                        if (op_array->type == ZEND_USER_FUNCTION) {
                                                if (op_array->static_variables) {
                                                        HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
index 30899982c8c138ee811a3516cda9f12214892f22..4288d8fb597ec77296f3526b1093ded293692cbb 100644 (file)
@@ -101,15 +101,6 @@ static zend_always_inline zend_function *zend_duplicate_function(zend_function *
                        /* reuse the same op_array structure */
                        return func;
                }
-               if (func->op_array.fn_flags & ZEND_ACC_PRIVATE) {
-                       /* For private methods we reuse the same op_array structure even if
-                        * static variables are used, because it will not end up being used
-                        * anyway. However we still need to addref as the dtor will delref. */
-                       if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
-                               GC_ADDREF(func->op_array.static_variables);
-                       }
-                       return func;
-               }
                return zend_duplicate_user_function(func);
        }
 }