From 70921ae3b2d88bac27ab8715f9e983d8f6e70d95 Mon Sep 17 00:00:00 2001 From: Jeff Welch Date: Sat, 5 Jan 2013 20:15:24 -0500 Subject: [PATCH] Fix #63914 Handle exceptions from the `zend_verify_arg_type` check in `zend_do_fcall_common_helper_SPEC` appropriately. --- Zend/zend_vm_def.h | 32 +++++++++++++++++--------------- Zend/zend_vm_execute.h | 32 +++++++++++++++++--------------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0aaed2e465a87..e1b16f8b5146f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1971,13 +1971,6 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) LOAD_OPLINE(); if (fbc->type == ZEND_INTERNAL_FUNCTION) { - temp_variable *ret = &EX_T(opline->result.var); - - MAKE_STD_ZVAL(ret->var.ptr); - ZVAL_NULL(ret->var.ptr); - ret->var.ptr_ptr = &ret->var.ptr; - ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; - if (fbc->common.arg_info) { zend_uint i=0; zval **p = (zval**)EX(function_state).arguments; @@ -1989,15 +1982,24 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) } } - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); - } else { - zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); - } + if (EXPECTED(EG(exception) == NULL)) { + temp_variable *ret = &EX_T(opline->result.var); - if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(&ret->var.ptr); + MAKE_STD_ZVAL(ret->var.ptr); + ZVAL_NULL(ret->var.ptr); + ret->var.ptr_ptr = &ret->var.ptr; + ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; + + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + } else { + zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); + } + + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&ret->var.ptr); + } } } else if (fbc->type == ZEND_USER_FUNCTION) { EX(original_return_value) = EG(return_value_ptr_ptr); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2fe18fbceec73..1419e7820623e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -523,13 +523,6 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR LOAD_OPLINE(); if (fbc->type == ZEND_INTERNAL_FUNCTION) { - temp_variable *ret = &EX_T(opline->result.var); - - MAKE_STD_ZVAL(ret->var.ptr); - ZVAL_NULL(ret->var.ptr); - ret->var.ptr_ptr = &ret->var.ptr; - ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; - if (fbc->common.arg_info) { zend_uint i=0; zval **p = (zval**)EX(function_state).arguments; @@ -541,15 +534,24 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR } } - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); - } else { - zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); - } + if (EXPECTED(EG(exception) == NULL)) { + temp_variable *ret = &EX_T(opline->result.var); - if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(&ret->var.ptr); + MAKE_STD_ZVAL(ret->var.ptr); + ZVAL_NULL(ret->var.ptr); + ret->var.ptr_ptr = &ret->var.ptr; + ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; + + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + } else { + zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); + } + + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&ret->var.ptr); + } } } else if (fbc->type == ZEND_USER_FUNCTION) { EX(original_return_value) = EG(return_value_ptr_ptr);