Patch 8.2.2664
Problem:    Vim9: not enough function arguments checked for string.
Solution:   Check in balloon functions.  Refactor function arguments.
Files:      src/typval.c, src/proto/typval.pro, src/filepath.c,
            src/evalfunc.c, src/mbyte.c, src/testdir/test_vim9_builtin.vim


*** ../vim-8.2.2663/src/typval.c        2021-03-22 22:21:22.781399262 +0100
--- src/typval.c        2021-03-27 18:23:46.848925028 +0100
***************
*** 344,355 ****
   * Give an error and return FAIL unless "tv" is a string.
   */
      int
! check_for_string(typval_T *tv, int arg)
  {
!     if (tv->v_type != VAR_STRING)
      {
!       if (arg > 0)
!           semsg(_(e_string_required_for_argument_nr), arg);
        else
            emsg(_(e_stringreq));
        return FAIL;
--- 344,355 ----
   * Give an error and return FAIL unless "tv" is a string.
   */
      int
! check_for_string_arg(typval_T *args, int idx)
  {
!     if (args[idx].v_type != VAR_STRING)
      {
!       if (idx >= 0)
!           semsg(_(e_string_required_for_argument_nr), idx + 1);
        else
            emsg(_(e_stringreq));
        return FAIL;
***************
*** 358,374 ****
  }
  
  /*
!  * Give an error and return FAIL unless "tv" is a non-empty string.
   */
      int
! check_for_nonempty_string(typval_T *tv, int arg)
  {
!     if (check_for_string(tv, arg) == FAIL)
        return FAIL;
!     if (tv->vval.v_string == NULL || *tv->vval.v_string == NUL)
      {
!       if (arg > 0)
!           semsg(_(e_non_empty_string_required_for_argument_nr), arg);
        else
            emsg(_(e_non_empty_string_required));
        return FAIL;
--- 358,374 ----
  }
  
  /*
!  * Give an error and return FAIL unless "args[idx]" is a non-empty string.
   */
      int
! check_for_nonempty_string_arg(typval_T *args, int idx)
  {
!     if (check_for_string_arg(args, idx) == FAIL)
        return FAIL;
!     if (args[idx].vval.v_string == NULL || *args[idx].vval.v_string == NUL)
      {
!       if (idx >= 0)
!           semsg(_(e_non_empty_string_required_for_argument_nr), idx + 1);
        else
            emsg(_(e_non_empty_string_required));
        return FAIL;
*** ../vim-8.2.2663/src/proto/typval.pro        2021-03-22 22:21:22.781399262 
+0100
--- src/proto/typval.pro        2021-03-27 18:20:44.001511309 +0100
***************
*** 9,16 ****
  varnumber_T tv_get_bool(typval_T *varp);
  varnumber_T tv_get_bool_chk(typval_T *varp, int *denote);
  float_T tv_get_float(typval_T *varp);
! int check_for_string(typval_T *tv, int arg);
! int check_for_nonempty_string(typval_T *tv, int arg);
  char_u *tv_get_string(typval_T *varp);
  char_u *tv_get_string_strict(typval_T *varp);
  char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
--- 9,16 ----
  varnumber_T tv_get_bool(typval_T *varp);
  varnumber_T tv_get_bool_chk(typval_T *varp, int *denote);
  float_T tv_get_float(typval_T *varp);
! int check_for_string_arg(typval_T *args, int idx);
! int check_for_nonempty_string_arg(typval_T *args, int idx);
  char_u *tv_get_string(typval_T *varp);
  char_u *tv_get_string_strict(typval_T *varp);
  char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
*** ../vim-8.2.2663/src/filepath.c      2021-03-22 22:21:22.781399262 +0100
--- src/filepath.c      2021-03-27 18:23:32.516970390 +0100
***************
*** 861,867 ****
      void
  f_executable(typval_T *argvars, typval_T *rettv)
  {
!     if (in_vim9script() && check_for_string(&argvars[0], 1) == FAIL)
        return;
  
      // Check in $PATH and also check directly if there is a directory name.
--- 861,867 ----
      void
  f_executable(typval_T *argvars, typval_T *rettv)
  {
!     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
        return;
  
      // Check in $PATH and also check directly if there is a directory name.
***************
*** 876,882 ****
  {
      char_u *p = NULL;
  
!     if (in_vim9script() && check_for_nonempty_string(&argvars[0], 1) == FAIL)
        return;
      (void)mch_can_exe(tv_get_string(&argvars[0]), &p, TRUE);
      rettv->v_type = VAR_STRING;
--- 876,882 ----
  {
      char_u *p = NULL;
  
!     if (in_vim9script() && check_for_nonempty_string_arg(argvars, 0) == FAIL)
        return;
      (void)mch_can_exe(tv_get_string(&argvars[0]), &p, TRUE);
      rettv->v_type = VAR_STRING;
***************
*** 893,899 ****
      char_u    *p;
      int               n;
  
!     if (in_vim9script() && check_for_string(&argvars[0], 1) == FAIL)
        return;
  #ifndef O_NONBLOCK
  # define O_NONBLOCK 0
--- 893,899 ----
      char_u    *p;
      int               n;
  
!     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
        return;
  #ifndef O_NONBLOCK
  # define O_NONBLOCK 0
***************
*** 918,924 ****
      void
  f_filewritable(typval_T *argvars, typval_T *rettv)
  {
!     if (in_vim9script() && check_for_string(&argvars[0], 1) == FAIL)
        return;
      rettv->vval.v_number = filewritable(tv_get_string(&argvars[0]));
  }
--- 918,924 ----
      void
  f_filewritable(typval_T *argvars, typval_T *rettv)
  {
!     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
        return;
      rettv->vval.v_number = filewritable(tv_get_string(&argvars[0]));
  }
***************
*** 942,948 ****
  
      rettv->vval.v_string = NULL;
      rettv->v_type = VAR_STRING;
!     if (in_vim9script() && check_for_nonempty_string(&argvars[0], 1) == FAIL)
        return;
  
  #ifdef FEAT_SEARCHPATH
--- 942,948 ----
  
      rettv->vval.v_string = NULL;
      rettv->v_type = VAR_STRING;
!     if (in_vim9script() && check_for_nonempty_string_arg(argvars, 0) == FAIL)
        return;
  
  #ifdef FEAT_SEARCHPATH
***************
*** 1023,1030 ****
      char_u    *fbuf = NULL;
      char_u    buf[NUMBUFLEN];
  
!     if (in_vim9script() && (check_for_string(&argvars[0], 1) == FAIL
!           || check_for_string(&argvars[1], 2) == FAIL))
        return;
      fname = tv_get_string_chk(&argvars[0]);
      mods = tv_get_string_buf_chk(&argvars[1], buf);
--- 1023,1030 ----
      char_u    *fbuf = NULL;
      char_u    buf[NUMBUFLEN];
  
!     if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL
!           || check_for_string_arg(argvars, 1) == FAIL))
        return;
      fname = tv_get_string_chk(&argvars[0]);
      mods = tv_get_string_buf_chk(&argvars[1], buf);
***************
*** 1135,1141 ****
      char_u    *perm = NULL;
      char_u    permbuf[] = "---------";
  
!     if (in_vim9script() && check_for_string(&argvars[0], 1) == FAIL)
        return;
      fname = tv_get_string(&argvars[0]);
  
--- 1135,1141 ----
      char_u    *perm = NULL;
      char_u    permbuf[] = "---------";
  
!     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
        return;
      fname = tv_get_string(&argvars[0]);
  
***************
*** 1154,1160 ****
      char_u    *fname;
      stat_T    st;
  
!     if (in_vim9script() && check_for_string(&argvars[0], 1) == FAIL)
        return;
  
      fname = tv_get_string(&argvars[0]);
--- 1154,1160 ----
      char_u    *fname;
      stat_T    st;
  
!     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
        return;
  
      fname = tv_get_string(&argvars[0]);
***************
*** 1184,1190 ****
      char_u    *fname;
      stat_T    st;
  
!     if (in_vim9script() && check_for_string(&argvars[0], 1) == FAIL)
        return;
      fname = tv_get_string(&argvars[0]);
      if (mch_stat((char *)fname, &st) >= 0)
--- 1184,1190 ----
      char_u    *fname;
      stat_T    st;
  
!     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
        return;
      fname = tv_get_string(&argvars[0]);
      if (mch_stat((char *)fname, &st) >= 0)
***************
*** 1230,1236 ****
      stat_T    st;
      char_u    *type = NULL;
  
!     if (in_vim9script() && check_for_string(&argvars[0], 1) == FAIL)
        return;
      fname = tv_get_string(&argvars[0]);
  
--- 1230,1236 ----
      stat_T    st;
      char_u    *type = NULL;
  
!     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
        return;
      fname = tv_get_string(&argvars[0]);
  
***************
*** 2411,2419 ****
      int               error = FALSE;
  
      if (in_vim9script()
!           && (check_for_string(&argvars[1], 2) == FAIL
!               || check_for_string(&argvars[2], 3) == FAIL
!               || check_for_string(&argvars[3], 4) == FAIL))
        return;
      save = (int)tv_get_number_chk(&argvars[0], &error);
      title = tv_get_string_chk(&argvars[1]);
--- 2411,2419 ----
      int               error = FALSE;
  
      if (in_vim9script()
!           && (check_for_string_arg(argvars, 1) == FAIL
!               || check_for_string_arg(argvars, 2) == FAIL
!               || check_for_string_arg(argvars, 3) == FAIL))
        return;
      save = (int)tv_get_number_chk(&argvars[0], &error);
      title = tv_get_string_chk(&argvars[1]);
*** ../vim-8.2.2663/src/evalfunc.c      2021-03-22 17:11:11.095967719 +0100
--- src/evalfunc.c      2021-03-27 18:40:25.761887049 +0100
***************
*** 2323,2330 ****
        }
        else
        {
!           char_u *mesg = tv_get_string_chk(&argvars[0]);
  
            if (mesg != NULL)
                // empty string removes the balloon
                post_balloon(balloonEval, *mesg == NUL ? NULL : mesg, NULL);
--- 2323,2334 ----
        }
        else
        {
!           char_u *mesg;
  
+           if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+               return;
+ 
+           mesg = tv_get_string_chk(&argvars[0]);
            if (mesg != NULL)
                // empty string removes the balloon
                post_balloon(balloonEval, *mesg == NUL ? NULL : mesg, NULL);
***************
*** 2338,2345 ****
  {
      if (rettv_list_alloc(rettv) == OK)
      {
!       char_u *msg = tv_get_string_chk(&argvars[0]);
  
        if (msg != NULL)
        {
            pumitem_T   *array;
--- 2342,2352 ----
  {
      if (rettv_list_alloc(rettv) == OK)
      {
!       char_u *msg;
  
+       if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+           return;
+       msg = tv_get_string_chk(&argvars[0]);
        if (msg != NULL)
        {
            pumitem_T   *array;
*** ../vim-8.2.2663/src/mbyte.c 2021-03-22 22:21:22.781399262 +0100
--- src/mbyte.c 2021-03-27 18:22:50.025105465 +0100
***************
*** 5551,5557 ****
      void
  f_charclass(typval_T *argvars, typval_T *rettv UNUSED)
  {
!     if (check_for_string(&argvars[0], 1) == FAIL)
        return;
      rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string);
  }
--- 5551,5557 ----
      void
  f_charclass(typval_T *argvars, typval_T *rettv UNUSED)
  {
!     if (check_for_string_arg(argvars, 0) == FAIL)
        return;
      rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string);
  }
*** ../vim-8.2.2663/src/testdir/test_vim9_builtin.vim   2021-03-25 
22:15:24.404073755 +0100
--- src/testdir/test_vim9_builtin.vim   2021-03-27 18:56:06.683542990 +0100
***************
*** 125,130 ****
--- 125,143 ----
    assert_equal(['0', 'one', '1', 'two', '2'], getline(1, 6))
  enddef
  
+ def Test_balloon_show()
+   CheckGui
+   CheckFeature balloon_eval
+ 
+   assert_fails('balloon_show(true)', 'E1174:')
+ enddef
+ 
+ def Test_balloon_split()
+   CheckFeature balloon_eval
+ 
+   assert_fails('balloon_split(true)', 'E1174:')
+ enddef
+ 
  def Test_browse()
    CheckFeature browse
  
***************
*** 142,150 ****
--- 155,168 ----
    CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 4')
  enddef
  
+ def Test_bufexists()
+   assert_fails('bufexists(true)', 'E1174')
+ enddef
+ 
  def Test_buflisted()
    var res: bool = buflisted('asdf')
    assert_equal(false, res)
+   assert_fails('buflisted(true)', 'E1174')
  enddef
  
  def Test_bufname()
***************
*** 176,181 ****
--- 194,201 ----
    only
    bwipe SomeFile
    bwipe OtherFile
+ 
+   assert_fails('bufwinid(true)', 'E1138')
  enddef
  
  def Test_call_call()
*** ../vim-8.2.2663/src/version.c       2021-03-27 15:40:07.979976135 +0100
--- src/version.c       2021-03-27 18:38:41.066199007 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2664,
  /**/

-- 
This planet has -- or rather had -- a problem, which was this: most
of the people living on it were unhappy for pretty much of the time.
Many solutions were suggested for this problem, but most of these
were largely concerned with the movements of small green pieces of
paper, which is odd because on the whole it wasn't the small green
pieces of paper that were unhappy.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// 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/202103271759.12RHxnka649406%40masaka.moolenaar.net.

Raspunde prin e-mail lui