summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-12-18 10:10:30 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-12-18 10:11:09 +0100
commit189f625e2b2a65edf406332bf87c81bab1b463af (patch)
tree6d071841bb15012acd1f0f32b6ed32e70fcdb9a2
parent3d50131ef7f5f55e9f0127246a1c9f6744d31817 (diff)
downloadphp-git-189f625e2b2a65edf406332bf87c81bab1b463af.tar.gz
Fix freeing of dynamic call name
We need to free op2 if the call construction fails. Also remove a redundant check for !call.
-rw-r--r--Zend/tests/dynamic_call_freeing.phpt28
-rw-r--r--Zend/zend_vm_def.h4
-rw-r--r--Zend/zend_vm_execute.h8
3 files changed, 30 insertions, 10 deletions
diff --git a/Zend/tests/dynamic_call_freeing.phpt b/Zend/tests/dynamic_call_freeing.phpt
new file mode 100644
index 0000000000..d124009295
--- /dev/null
+++ b/Zend/tests/dynamic_call_freeing.phpt
@@ -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
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index a1cef14b75..1963760112 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -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);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 11bc82c1c4..d80a5f704d 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -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);