diff --git a/Zend/tests/dynamic_call_freeing.phpt b/Zend/tests/dynamic_call_freeing.phpt new file mode 100644 index 00000000000..d1240092952 --- /dev/null +++ b/Zend/tests/dynamic_call_freeing.phpt @@ -0,0 +1,28 @@ +--TEST-- +Freeing of function "name" when dynamic call fails +--FILE-- +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 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1ff9a81eadc..d041d168938 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3816,11 +3816,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) { @@ -3832,8 +3832,6 @@ ZEND_VM_C_LABEL(try_function_name): } HANDLE_EXCEPTION(); } - } else if (UNEXPECTED(!call)) { - HANDLE_EXCEPTION(); } call->prev_execute_data = EX(call); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5e444817c79..b015558084b 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2951,8 +2951,6 @@ try_function_name: } HANDLE_EXCEPTION(); } - } else if (UNEXPECTED(!call)) { - HANDLE_EXCEPTION(); } call->prev_execute_data = EX(call); @@ -3107,11 +3105,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) { @@ -3123,8 +3121,6 @@ try_function_name: } HANDLE_EXCEPTION(); } - } else if (UNEXPECTED(!call)) { - HANDLE_EXCEPTION(); } call->prev_execute_data = EX(call); @@ -3240,8 +3236,6 @@ try_function_name: } HANDLE_EXCEPTION(); } - } else if (UNEXPECTED(!call)) { - HANDLE_EXCEPTION(); } call->prev_execute_data = EX(call);