Patch 8.2.4224
Problem:    Vim9: no error when using a number for map() second argument
Solution:   Disallow number to string conversion. (closes #9630)
Files:      src/eval.c, src/evalfunc.c, src/testdir/test_vim9_builtin.vim


*** ../vim-8.2.4223/src/eval.c  2022-01-26 16:45:16.934506694 +0000
--- src/eval.c  2022-01-26 17:37:24.284951289 +0000
***************
*** 291,297 ****
      }
      else
      {
!       s = tv_get_string_buf_chk(expr, buf);
        if (s == NULL)
            return FAIL;
        s = skipwhite(s);
--- 291,297 ----
      }
      else
      {
!       s = tv_get_string_buf_chk_strict(expr, buf, TRUE);
        if (s == NULL)
            return FAIL;
        s = skipwhite(s);
*** ../vim-8.2.4223/src/evalfunc.c      2022-01-22 10:59:58.443950062 +0000
--- src/evalfunc.c      2022-01-26 18:23:45.687641629 +0000
***************
*** 491,503 ****
      static int
  arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
  {
!     if (type->tt_type == VAR_FUNC
!           && !(type->tt_member->tt_type == VAR_BOOL
                || type->tt_member->tt_type == VAR_NUMBER
                || type->tt_member->tt_type == VAR_UNKNOWN
                || type->tt_member->tt_type == VAR_ANY))
      {
!       arg_type_mismatch(&t_func_bool, type, context->arg_idx + 1);
        return FAIL;
      }
      return OK;
--- 491,516 ----
      static int
  arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
  {
!     if (type->tt_type == VAR_STRING
!           || type->tt_type == VAR_PARTIAL
!           || type == &t_unknown
!           || type == &t_any)
!       return OK;
! 
!     if (type->tt_type == VAR_FUNC)
!     {
!       if (!(type->tt_member->tt_type == VAR_BOOL
                || type->tt_member->tt_type == VAR_NUMBER
                || type->tt_member->tt_type == VAR_UNKNOWN
                || type->tt_member->tt_type == VAR_ANY))
+       {
+           arg_type_mismatch(&t_func_bool, type, context->arg_idx + 1);
+           return FAIL;
+       }
+     }
+     else
      {
!       semsg(_(e_string_or_function_required_for_argument_nr), 2);
        return FAIL;
      }
      return OK;
***************
*** 509,535 ****
      static int
  arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
  {
!     if (type->tt_type == VAR_FUNC
!           && type->tt_member != &t_any
!           && type->tt_member != &t_unknown)
!     {
!       type_T *expected = NULL;
  
!       if (context->arg_types[0].type_curr->tt_type == VAR_LIST
!               || context->arg_types[0].type_curr->tt_type == VAR_DICT)
!           expected = context->arg_types[0].type_curr->tt_member;
!       else if (context->arg_types[0].type_curr->tt_type == VAR_STRING)
!           expected = &t_string;
!       else if (context->arg_types[0].type_curr->tt_type == VAR_BLOB)
!           expected = &t_number;
!       if (expected != NULL)
        {
!           type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC, NULL, NULL};
  
!           t_func_exp.tt_member = expected;
!           return check_arg_type(&t_func_exp, type, context);
        }
      }
      return OK;
  }
  
--- 522,561 ----
      static int
  arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
  {
!     if (type->tt_type == VAR_STRING
!           || type->tt_type == VAR_PARTIAL
!           || type == &t_unknown
!           || type == &t_any)
!       return OK;
  
!     if (type->tt_type == VAR_FUNC)
!     {
!       if (type->tt_member != &t_any
!           && type->tt_member != &t_unknown)
        {
!           type_T *expected = NULL;
! 
!           if (context->arg_types[0].type_curr->tt_type == VAR_LIST
!                   || context->arg_types[0].type_curr->tt_type == VAR_DICT)
!               expected = context->arg_types[0].type_curr->tt_member;
!           else if (context->arg_types[0].type_curr->tt_type == VAR_STRING)
!               expected = &t_string;
!           else if (context->arg_types[0].type_curr->tt_type == VAR_BLOB)
!               expected = &t_number;
!           if (expected != NULL)
!           {
!               type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC, NULL, 
NULL};
  
!               t_func_exp.tt_member = expected;
!               return check_arg_type(&t_func_exp, type, context);
!           }
        }
      }
+     else
+     {
+       semsg(_(e_string_or_function_required_for_argument_nr), 2);
+       return FAIL;
+     }
      return OK;
  }
  
*** ../vim-8.2.4223/src/testdir/test_vim9_builtin.vim   2022-01-18 
21:42:33.836745971 +0000
--- src/testdir/test_vim9_builtin.vim   2022-01-26 18:17:10.087209666 +0000
***************
*** 1275,1280 ****
--- 1275,1281 ----
  
  def Test_filter()
    CheckDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type 
mismatch, expected list<any> but got float', 'E1251: List, Dictionary, Blob or 
String required for argument 1'])
+   CheckDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function 
required for argument 2', 'E1024: Using a Number as a String'])
  
    var lines =<< trim END
      def F(i: number, v: any): string
***************
*** 2153,2158 ****
--- 2154,2160 ----
      CheckDefAndScriptFailure(['map(test_null_channel(), "1")'], ['E1013: 
Argument 1: type mismatch, expected list<any> but got channel', 'E1251: List, 
Dictionary, Blob or String required for argument 1'])
    endif
    CheckDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type 
mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or 
String required for argument 1'])
+   CheckDefAndScriptFailure(['map([1, 2], 4)'], ['E1256: String or function 
required for argument 2', 'E1024: Using a Number as a String'])
  
    # type of dict remains dict<any> even when type of values changes
    # same for list
*** ../vim-8.2.4223/src/version.c       2022-01-26 16:45:16.934506694 +0000
--- src/version.c       2022-01-26 18:02:56.274980221 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4224,
  /**/

-- 
LETTERS TO THE EDITOR (The Times of London)

Dear Sir,

I am firmly opposed to the spread of microchips either to the home or
to the office.  We have more than enough of them foisted upon us in
public places.  They are a disgusting Americanism, and can only result
in the farmers being forced to grow smaller potatoes, which in turn
will cause massive unemployment in the already severely depressed
agricultural industry.

Yours faithfully,
        Capt. Quinton D'Arcy, J. P.
        Sevenoaks

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20220126182647.ABE551C05DA%40moolenaar.net.

Raspunde prin e-mail lui