]> granicus.if.org Git - php/commitdiff
Fix freeing of dynamic call name
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Dec 2019 09:10:30 +0000 (10:10 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Dec 2019 09:11:09 +0000 (10:11 +0100)
We need to free op2 if the call construction fails.

Also remove a redundant check for !call.

Zend/tests/dynamic_call_freeing.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/dynamic_call_freeing.phpt b/Zend/tests/dynamic_call_freeing.phpt
new file mode 100644 (file)
index 0000000..d124009
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Freeing of function "name" when dynamic call fails
+--FILE--
+<?php
+
+try {
+    $bar = "bar";
+    ("foo" . $bar)();
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    $bar = ["bar"];
+    (["foo"] + $bar)();
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    (new stdClass)();
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+Call to undefined function foobar()
+Function name must be a string
+Function name must be a string
index a1cef14b75f17819ca781631331079fbd4593274..1963760112f904c6297d7c54d5b7f6b7f0e39406 100644 (file)
@@ -3344,11 +3344,11 @@ ZEND_VM_C_LABEL(try_function_name):
                call = NULL;
        }
 
+       FREE_OP2();
        if (UNEXPECTED(!call)) {
                HANDLE_EXCEPTION();
        }
 
-       FREE_OP2();
        if (OP2_TYPE & (IS_VAR|IS_TMP_VAR)) {
                if (UNEXPECTED(EG(exception))) {
                        if (call) {
@@ -3360,8 +3360,6 @@ ZEND_VM_C_LABEL(try_function_name):
                        }
                        HANDLE_EXCEPTION();
                }
-       } else if (UNEXPECTED(!call)) {
-               HANDLE_EXCEPTION();
        }
 
        call->prev_execute_data = EX(call);
index 11bc82c1c45e86837d73783d2fac9e9b02b172cf..d80a5f704d19d52ff8874fe2ca2cbaad3fa530be 100644 (file)
@@ -2137,8 +2137,6 @@ try_function_name:
                        }
                        HANDLE_EXCEPTION();
                }
-       } else if (UNEXPECTED(!call)) {
-               HANDLE_EXCEPTION();
        }
 
        call->prev_execute_data = EX(call);
@@ -2313,11 +2311,11 @@ try_function_name:
                call = NULL;
        }
 
+       zval_ptr_dtor_nogc(free_op2);
        if (UNEXPECTED(!call)) {
                HANDLE_EXCEPTION();
        }
 
-       zval_ptr_dtor_nogc(free_op2);
        if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
                if (UNEXPECTED(EG(exception))) {
                        if (call) {
@@ -2329,8 +2327,6 @@ try_function_name:
                        }
                        HANDLE_EXCEPTION();
                }
-       } else if (UNEXPECTED(!call)) {
-               HANDLE_EXCEPTION();
        }
 
        call->prev_execute_data = EX(call);
@@ -2446,8 +2442,6 @@ try_function_name:
                        }
                        HANDLE_EXCEPTION();
                }
-       } else if (UNEXPECTED(!call)) {
-               HANDLE_EXCEPTION();
        }
 
        call->prev_execute_data = EX(call);