Skip to content

Commit ee65e92

Browse files
committed
Check internal function type consistency in zend_call_function
We do this for calls in the engine, but not those going through zend_call_function().
1 parent 6777630 commit ee65e92

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

Zend/zend_execute.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ static zend_never_inline ZEND_ATTRIBUTE_UNUSED bool zend_verify_internal_arg_typ
11451145
/* Determine whether an internal call should throw, because the passed arguments violate
11461146
* an arginfo constraint. This is only checked in debug builds. In release builds, we
11471147
* trust that arginfo matches what is enforced by zend_parse_parameters. */
1148-
static zend_always_inline bool zend_internal_call_should_throw(zend_function *fbc, zend_execute_data *call)
1148+
ZEND_API bool zend_internal_call_should_throw(zend_function *fbc, zend_execute_data *call)
11491149
{
11501150
if (fbc->internal_function.handler == ZEND_FN(pass)) {
11511151
/* Be lenient about the special pass function. */
@@ -1172,7 +1172,7 @@ static zend_always_inline bool zend_internal_call_should_throw(zend_function *fb
11721172
return 0;
11731173
}
11741174

1175-
static ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc)
1175+
ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc)
11761176
{
11771177
zend_error(E_ERROR, "Arginfo / zpp mismatch during call of %s%s%s()",
11781178
fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "",
@@ -1274,7 +1274,7 @@ static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, con
12741274
fclass, fsep, fname, returned_msg, returned_kind);
12751275
}
12761276

1277-
static bool zend_verify_internal_return_type(zend_function *zf, zval *ret)
1277+
ZEND_API bool zend_verify_internal_return_type(zend_function *zf, zval *ret)
12781278
{
12791279
zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1;
12801280

Zend/zend_execute.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ ZEND_API bool zend_verify_ref_array_assignable(zend_reference *ref);
7979
ZEND_API bool zend_check_user_type_slow(
8080
zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, bool is_return_type);
8181

82+
#if ZEND_DEBUG
83+
ZEND_API bool zend_internal_call_should_throw(zend_function *fbc, zend_execute_data *call);
84+
ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc);
85+
ZEND_API bool zend_verify_internal_return_type(zend_function *zf, zval *ret);
86+
#endif
8287

8388
#define ZEND_REF_TYPE_SOURCES(ref) \
8489
(ref)->sources

Zend/zend_execute_API.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,9 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_
887887
EG(jit_trace_num) = orig_jit_trace_num;
888888
} else {
889889
ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION);
890+
#if ZEND_DEBUG
891+
bool should_throw = zend_internal_call_should_throw(func, call);
892+
#endif
890893
ZVAL_NULL(fci->retval);
891894
call->prev_execute_data = EG(current_execute_data);
892895
EG(current_execute_data) = call;
@@ -902,6 +905,18 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_
902905
zend_array_release(call->extra_named_params);
903906
}
904907

908+
#if ZEND_DEBUG
909+
if (!EG(exception) && call->func) {
910+
if (should_throw) {
911+
zend_internal_call_arginfo_violation(call->func);
912+
}
913+
ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
914+
zend_verify_internal_return_type(call->func, fci->retval));
915+
ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
916+
? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval));
917+
}
918+
#endif
919+
905920
if (EG(exception)) {
906921
zval_ptr_dtor(fci->retval);
907922
ZVAL_UNDEF(fci->retval);

0 commit comments

Comments
 (0)