From 603b9c43cb993e6a744fda3bbed7c4617807f428 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 2 Sep 2019 14:30:51 +0200 Subject: [PATCH] Add arg type assertions to DO_ICALL Now that DO_ICALL is also used for functions with type hints, we should include the arginfo sanity check assertions in there as well. --- Zend/zend_vm_def.h | 11 ++++++++++- Zend/zend_vm_execute.h | 22 ++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 27085686ea..4eb0dc80b2 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4010,6 +4010,15 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL)) call->prev_execute_data = execute_data; EG(current_execute_data) = call; +#if ZEND_DEBUG + /* Type checks for internal functions are usually only performed by zpp. + * In debug mode we additionally run arginfo checks to detect cases where + * arginfo and zpp went out of sync. */ + zend_bool wrong_arg_types = + (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) && + !zend_verify_internal_arg_types(fbc, call); +#endif + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); @@ -4017,6 +4026,7 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL)) #if ZEND_DEBUG if (!EG(exception) && call->func) { + ZEND_ASSERT(!wrong_arg_types && "Arginfo / zpp type mismatch?"); ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || zend_verify_internal_return_type(call->func, ret)); ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) @@ -4101,7 +4111,6 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) call->prev_execute_data = execute_data; EG(current_execute_data) = call; - #if ZEND_DEBUG /* Type checks for internal functions are usually only performed by zpp. * In debug mode we additionally run arginfo checks to detect cases where diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 3abd9708fc..f65bba6c67 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1266,6 +1266,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV call->prev_execute_data = execute_data; EG(current_execute_data) = call; +#if ZEND_DEBUG + /* Type checks for internal functions are usually only performed by zpp. + * In debug mode we additionally run arginfo checks to detect cases where + * arginfo and zpp went out of sync. */ + zend_bool wrong_arg_types = + (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) && + !zend_verify_internal_arg_types(fbc, call); +#endif + ret = 0 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); @@ -1273,6 +1282,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV #if ZEND_DEBUG if (!EG(exception) && call->func) { + ZEND_ASSERT(!wrong_arg_types && "Arginfo / zpp type mismatch?"); ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || zend_verify_internal_return_type(call->func, ret)); ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) @@ -1311,6 +1321,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV call->prev_execute_data = execute_data; EG(current_execute_data) = call; +#if ZEND_DEBUG + /* Type checks for internal functions are usually only performed by zpp. + * In debug mode we additionally run arginfo checks to detect cases where + * arginfo and zpp went out of sync. */ + zend_bool wrong_arg_types = + (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) && + !zend_verify_internal_arg_types(fbc, call); +#endif + ret = 1 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); @@ -1318,6 +1337,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV #if ZEND_DEBUG if (!EG(exception) && call->func) { + ZEND_ASSERT(!wrong_arg_types && "Arginfo / zpp type mismatch?"); ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || zend_verify_internal_return_type(call->func, ret)); ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) @@ -1425,7 +1445,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S call->prev_execute_data = execute_data; EG(current_execute_data) = call; - #if ZEND_DEBUG /* Type checks for internal functions are usually only performed by zpp. * In debug mode we additionally run arginfo checks to detect cases where @@ -1504,7 +1523,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S call->prev_execute_data = execute_data; EG(current_execute_data) = call; - #if ZEND_DEBUG /* Type checks for internal functions are usually only performed by zpp. * In debug mode we additionally run arginfo checks to detect cases where -- 2.40.0