diff src/vim9cmds.c @ 30166:d1c04b4dc60d v9.0.0419

patch 9.0.0419: the :defer command does not check the function arguments Commit: https://github.com/vim/vim/commit/169003289fb4b2ad18fd7f5807e0d05efff0be85 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Sep 8 19:51:45 2022 +0100 patch 9.0.0419: the :defer command does not check the function arguments Problem: The :defer command does not check the function argument count and types. Solution: Check the function arguments when adding a deferred function.
author Bram Moolenaar <Bram@vim.org>
date Thu, 08 Sep 2022 21:00:04 +0200
parents 4eac06fb0191
children 6472aa128651
line wrap: on
line diff
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -1685,33 +1685,12 @@ compile_eval(char_u *arg, cctx_T *cctx)
 }
 
 /*
- * Get the local variable index for deferred function calls.
- * Reserve it when not done already.
- * Returns zero for failure.
- */
-    int
-get_defer_var_idx(cctx_T *cctx)
-{
-    dfunc_T	*dfunc = ((dfunc_T *)def_functions.ga_data)
-					       + cctx->ctx_ufunc->uf_dfunc_idx;
-    if (dfunc->df_defer_var_idx == 0)
-    {
-	lvar_T *lvar = reserve_local(cctx, (char_u *)"@defer@", 7,
-							    TRUE, &t_list_any);
-	if (lvar == NULL)
-	    return 0;
-	dfunc->df_defer_var_idx = lvar->lv_idx + 1;
-    }
-    return dfunc->df_defer_var_idx;
-}
-
-/*
  * Compile "defer func(arg)".
  */
     char_u *
 compile_defer(char_u *arg_start, cctx_T *cctx)
 {
-    char_u	*p;
+    char_u	*paren;
     char_u	*arg = arg_start;
     int		argcount = 0;
     int		defer_var_idx;
@@ -1720,13 +1699,13 @@ compile_defer(char_u *arg_start, cctx_T 
 
     // Get a funcref for the function name.
     // TODO: better way to find the "(".
-    p = vim_strchr(arg, '(');
-    if (p == NULL)
+    paren = vim_strchr(arg, '(');
+    if (paren == NULL)
     {
 	semsg(_(e_missing_parenthesis_str), arg);
 	return NULL;
     }
-    *p = NUL;
+    *paren = NUL;
     func_idx = find_internal_func(arg);
     if (func_idx >= 0)
 	// TODO: better type
@@ -1734,7 +1713,7 @@ compile_defer(char_u *arg_start, cctx_T 
 							   &t_func_any, FALSE);
     else if (compile_expr0(&arg, cctx) == FAIL)
 	return NULL;
-    *p = '(';
+    *paren = '(';
 
     // check for function type
     type = get_type_on_stack(cctx, 0);
@@ -1745,11 +1724,22 @@ compile_defer(char_u *arg_start, cctx_T 
     }
 
     // compile the arguments
-    arg = skipwhite(p + 1);
+    arg = skipwhite(paren + 1);
     if (compile_arguments(&arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL)
 	return NULL;
 
-    // TODO: check argument count with "type"
+    if (func_idx >= 0)
+    {
+	type2_T	*argtypes = NULL;
+	type2_T	shuffled_argtypes[MAX_FUNC_ARGS];
+
+	if (check_internal_func_args(cctx, func_idx, argcount, FALSE,
+					 &argtypes, shuffled_argtypes) == FAIL)
+	    return NULL;
+    }
+    else if (check_func_args_from_type(cctx, type, argcount, TRUE,
+							    arg_start) == FAIL)
+	return NULL;
 
     defer_var_idx = get_defer_var_idx(cctx);
     if (defer_var_idx == 0)