Patch 8.2.2172
Problem:    Vim9: number of arguments is not always checked. (Yegappan
            Lakshmanan)
Solution:   Check number of arguments when calling function by name.
Files:      src/userfunc.c, src/proto/userfunc.pro, src/vim9execute.c,
            src/testdir/test_vim9_func.vim, src/testdir/test_vim9_script.vim


*** ../vim-8.2.2171/src/userfunc.c      2020-12-20 17:47:49.253182274 +0100
--- src/userfunc.c      2020-12-20 20:56:12.843590663 +0100
***************
*** 1834,1839 ****
--- 1834,1855 ----
  }
  
  /*
+  * Check the argument count for user function "fp".
+  * Return FCERR_UNKNOWN if OK, FCERR_TOOFEW or FCERR_TOOMANY otherwise.
+  */
+     int
+ check_user_func_argcount(ufunc_T *fp, int argcount)
+ {
+     int regular_args = fp->uf_args.ga_len;
+ 
+     if (argcount < regular_args - fp->uf_def_args.ga_len)
+       return FCERR_TOOFEW;
+     else if (!has_varargs(fp) && argcount > regular_args)
+       return FCERR_TOOMANY;
+     return FCERR_UNKNOWN;
+ }
+ 
+ /*
   * Call a user function after checking the arguments.
   */
      int
***************
*** 1846,1860 ****
        dict_T      *selfdict)
  {
      int error;
-     int regular_args = fp->uf_args.ga_len;
  
      if (fp->uf_flags & FC_RANGE && funcexe->doesrange != NULL)
        *funcexe->doesrange = TRUE;
!     if (argcount < regular_args - fp->uf_def_args.ga_len)
!       error = FCERR_TOOFEW;
!     else if (!has_varargs(fp) && argcount > regular_args)
!       error = FCERR_TOOMANY;
!     else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
        error = FCERR_DICT;
      else
      {
--- 1862,1874 ----
        dict_T      *selfdict)
  {
      int error;
  
      if (fp->uf_flags & FC_RANGE && funcexe->doesrange != NULL)
        *funcexe->doesrange = TRUE;
!     error = check_user_func_argcount(fp, argcount);
!     if (error != FCERR_UNKNOWN)
!       return error;
!     if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
        error = FCERR_DICT;
      else
      {
*** ../vim-8.2.2171/src/proto/userfunc.pro      2020-12-20 17:47:49.253182274 
+0100
--- src/proto/userfunc.pro      2020-12-20 20:55:48.827682599 +0100
***************
*** 18,23 ****
--- 18,24 ----
  void funcdepth_decrement(void);
  int funcdepth_get(void);
  void funcdepth_restore(int depth);
+ int check_user_func_argcount(ufunc_T *fp, int argcount);
  int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, 
typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict);
  void save_funccal(funccal_entry_T *entry);
  void restore_funccal(void);
*** ../vim-8.2.2171/src/vim9execute.c   2020-12-20 17:47:49.253182274 +0100
--- src/vim9execute.c   2020-12-20 20:55:42.915705255 +0100
***************
*** 606,611 ****
--- 606,622 ----
        return FAIL;
      if (ufunc->uf_def_status == UF_COMPILED)
      {
+       int error = check_user_func_argcount(ufunc, argcount);
+ 
+       if (error != FCERR_UNKNOWN)
+       {
+           if (error == FCERR_TOOMANY)
+               semsg(_(e_toomanyarg), ufunc->uf_name);
+           else
+               semsg(_(e_toofewarg), ufunc->uf_name);
+           return FAIL;
+       }
+ 
        // The function has been compiled, can call it quickly.  For a function
        // that was defined later: we can call it directly next time.
        if (iptr != NULL)
*** ../vim-8.2.2171/src/testdir/test_vim9_func.vim      2020-12-20 
17:47:49.257182258 +0100
--- src/testdir/test_vim9_func.vim      2020-12-20 21:04:35.512663131 +0100
***************
*** 470,475 ****
--- 470,494 ----
    delete('Xscript')
  enddef
  
+ def Test_call_funcref_wrong_args()
+   var head =<< trim END
+       vim9script
+       def Func3(a1: string, a2: number, a3: list<number>)
+         echo a1 .. a2 .. a3[0]
+       enddef
+       def Testme()
+         var funcMap: dict<func> = {func: Func3}
+   END
+   var tail =<< trim END
+       enddef
+       Testme()
+   END
+   CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
+ 
+   CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
+   CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 
'E118:')
+ enddef
+ 
  def Test_call_lambda_args()
    CheckDefFailure(['echo {i -> 0}()'],
                    'E119: Not enough arguments for function: {i -> 0}()')
*** ../vim-8.2.2171/src/testdir/test_vim9_script.vim    2020-12-20 
15:43:27.667305001 +0100
--- src/testdir/test_vim9_script.vim    2020-12-20 21:06:49.307724159 +0100
***************
*** 1312,1323 ****
    # FuncNo() is not redefined
    writefile(first_lines + nono_lines, 'Xreloaded.vim')
    source Xreloaded.vim
!   g:DoCheck()
  
    # FuncNo() is back
    writefile(first_lines + withno_lines, 'Xreloaded.vim')
    source Xreloaded.vim
!   g:DoCheck()
  
    delete('Xreloaded.vim')
  enddef
--- 1312,1323 ----
    # FuncNo() is not redefined
    writefile(first_lines + nono_lines, 'Xreloaded.vim')
    source Xreloaded.vim
!   g:DoCheck(false)
  
    # FuncNo() is back
    writefile(first_lines + withno_lines, 'Xreloaded.vim')
    source Xreloaded.vim
!   g:DoCheck(false)
  
    delete('Xreloaded.vim')
  enddef
*** ../vim-8.2.2171/src/version.c       2020-12-20 17:59:49.314315870 +0100
--- src/version.c       2020-12-20 20:53:06.576304575 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2172,
  /**/

-- 
I recommend ordering large cargo containers of paper towels to make up
whatever budget underruns you have.  Paper products are always useful and they
have the advantage of being completely flushable if you need to make room in
the storage area later.
                                (Scott Adams - The Dilbert principle)

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202012202011.0BKKBFKo2007427%40masaka.moolenaar.net.

Raspunde prin e-mail lui