Patch 8.2.2117
Problem:    Some functions use any value as a string.
Solution:   Check that the value is a non-empty string.
Files:      src/typval.c, src/proto/typval.pro, src/mbyte.c, src/filepath.c,
            src/testdir/test_vim9_builtin.vim, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2116/src/typval.c        2020-11-18 17:17:11.961928659 +0100
--- src/typval.c        2020-12-09 12:20:22.162620618 +0100
***************
*** 341,346 ****
--- 341,362 ----
  #endif
  
  /*
+  * Give an error and return FAIL unless "tv" is a non-empty string.
+  */
+     int
+ check_for_string(typval_T *tv)
+ {
+     if (tv->v_type != VAR_STRING
+           || tv->vval.v_string == NULL
+           || *tv->vval.v_string == NUL)
+     {
+       emsg(_(e_stringreq));
+       return FAIL;
+     }
+     return OK;
+ }
+ 
+ /*
   * Get the string value of a variable.
   * If it is a Number variable, the number is converted into a string.
   * tv_get_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
*** ../vim-8.2.2116/src/proto/typval.pro        2020-09-01 23:05:57.812835372 
+0200
--- src/proto/typval.pro        2020-12-09 12:21:21.498434049 +0100
***************
*** 9,14 ****
--- 9,15 ----
  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);
  char_u *tv_get_string(typval_T *varp);
  char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
  char_u *tv_get_string_chk(typval_T *varp);
*** ../vim-8.2.2116/src/mbyte.c 2020-08-30 19:26:40.736556825 +0200
--- src/mbyte.c 2020-12-09 12:25:43.889584858 +0100
***************
*** 5551,5563 ****
      void
  f_charclass(typval_T *argvars, typval_T *rettv UNUSED)
  {
!     if (argvars[0].v_type != VAR_STRING
!           || argvars[0].vval.v_string == NULL
!           || *argvars[0].vval.v_string == NUL)
!     {
!       emsg(_(e_stringreq));
        return;
-     }
      rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string);
  }
  #endif
--- 5551,5558 ----
      void
  f_charclass(typval_T *argvars, typval_T *rettv UNUSED)
  {
!     if (check_for_string(&argvars[0]) == FAIL)
        return;
      rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string);
  }
  #endif
*** ../vim-8.2.2116/src/filepath.c      2020-10-24 20:49:37.494683051 +0200
--- src/filepath.c      2020-12-09 12:35:25.495620783 +0100
***************
*** 861,870 ****
      void
  f_executable(typval_T *argvars, typval_T *rettv)
  {
!     char_u *name = tv_get_string(&argvars[0]);
  
      // Check in $PATH and also check directly if there is a directory name.
!     rettv->vval.v_number = mch_can_exe(name, NULL, TRUE);
  }
  
  /*
--- 861,871 ----
      void
  f_executable(typval_T *argvars, typval_T *rettv)
  {
!     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
!       return;
  
      // Check in $PATH and also check directly if there is a directory name.
!     rettv->vval.v_number = mch_can_exe(tv_get_string(&argvars[0]), NULL, 
TRUE);
  }
  
  /*
***************
*** 875,880 ****
--- 876,883 ----
  {
      char_u *p = NULL;
  
+     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
+       return;
      (void)mch_can_exe(tv_get_string(&argvars[0]), &p, TRUE);
      rettv->v_type = VAR_STRING;
      rettv->vval.v_string = p;
***************
*** 890,895 ****
--- 893,900 ----
      char_u    *p;
      int               n;
  
+     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
+       return;
  #ifndef O_NONBLOCK
  # define O_NONBLOCK 0
  #endif
***************
*** 913,918 ****
--- 918,925 ----
      void
  f_filewritable(typval_T *argvars, typval_T *rettv)
  {
+     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
+       return;
      rettv->vval.v_number = filewritable(tv_get_string(&argvars[0]));
  }
  
***************
*** 935,940 ****
--- 942,949 ----
  
      rettv->vval.v_string = NULL;
      rettv->v_type = VAR_STRING;
+     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
+       return;
  
  #ifdef FEAT_SEARCHPATH
      fname = tv_get_string(&argvars[0]);
***************
*** 1014,1019 ****
--- 1023,1031 ----
      char_u    *fbuf = NULL;
      char_u    buf[NUMBUFLEN];
  
+     if (in_vim9script() && (check_for_string(&argvars[0]) == FAIL
+           || check_for_string(&argvars[1]) == FAIL))
+       return;
      fname = tv_get_string_chk(&argvars[0]);
      mods = tv_get_string_buf_chk(&argvars[1], buf);
      if (fname == NULL || mods == NULL)
***************
*** 1122,1127 ****
--- 1134,1141 ----
      char_u    *perm = NULL;
      char_u    permbuf[] = "---------";
  
+     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
+       return;
      fname = tv_get_string(&argvars[0]);
  
      rettv->v_type = VAR_STRING;
***************
*** 1139,1148 ****
      char_u    *fname;
      stat_T    st;
  
!     fname = tv_get_string(&argvars[0]);
! 
!     rettv->v_type = VAR_NUMBER;
  
      if (mch_stat((char *)fname, &st) >= 0)
      {
        if (mch_isdir(fname))
--- 1153,1162 ----
      char_u    *fname;
      stat_T    st;
  
!     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
!       return;
  
+     fname = tv_get_string(&argvars[0]);
      if (mch_stat((char *)fname, &st) >= 0)
      {
        if (mch_isdir(fname))
***************
*** 1169,1176 ****
      char_u    *fname;
      stat_T    st;
  
      fname = tv_get_string(&argvars[0]);
- 
      if (mch_stat((char *)fname, &st) >= 0)
        rettv->vval.v_number = (varnumber_T)st.st_mtime;
      else
--- 1183,1191 ----
      char_u    *fname;
      stat_T    st;
  
+     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
+       return;
      fname = tv_get_string(&argvars[0]);
      if (mch_stat((char *)fname, &st) >= 0)
        rettv->vval.v_number = (varnumber_T)st.st_mtime;
      else
***************
*** 1214,1219 ****
--- 1229,1236 ----
      stat_T    st;
      char_u    *type = NULL;
  
+     if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
+       return;
      fname = tv_get_string(&argvars[0]);
  
      rettv->v_type = VAR_STRING;
*** ../vim-8.2.2116/src/testdir/test_vim9_builtin.vim   2020-12-05 
21:46:50.154387600 +0100
--- src/testdir/test_vim9_builtin.vim   2020-12-09 12:35:57.555500410 +0100
***************
*** 185,190 ****
--- 185,202 ----
    count('ABC ABC ABC', 'b', false)->assert_equal(0)
  enddef
  
+ def Test_executable()
+   CheckDefExecFailure(['echo executable(true)'], 'E928:')
+   CheckDefExecFailure(['echo executable(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo executable("")'], 'E928:')
+ enddef
+ 
+ def Test_exepath()
+   CheckDefExecFailure(['echo exepath(true)'], 'E928:')
+   CheckDefExecFailure(['echo exepath(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo exepath("")'], 'E928:')
+ enddef
+ 
  def Test_expand()
    split SomeFile
    expand('%', true, true)->assert_equal(['SomeFile'])
***************
*** 241,246 ****
--- 253,291 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
+ def Test_filereadable()
+   CheckDefExecFailure(['echo filereadable(true)'], 'E928:')
+   CheckDefExecFailure(['echo filereadable(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo filereadable("")'], 'E928:')
+ enddef
+ 
+ def Test_filewritable()
+   CheckDefExecFailure(['echo filewritable(true)'], 'E928:')
+   CheckDefExecFailure(['echo filewritable(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo filewritable("")'], 'E928:')
+ enddef
+ 
+ def Test_finddir()
+   CheckDefExecFailure(['echo finddir(true)'], 'E928:')
+   CheckDefExecFailure(['echo finddir(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo finddir("")'], 'E928:')
+ enddef
+ 
+ def Test_findfile()
+   CheckDefExecFailure(['echo findfile(true)'], 'E928:')
+   CheckDefExecFailure(['echo findfile(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo findfile("")'], 'E928:')
+ enddef
+ 
+ def Test_fnamemodify()
+   CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E928:')
+   CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E928:')
+   CheckDefExecFailure(['echo fnamemodify("", ":p")'], 'E928:')
+   CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E928:')
+   CheckDefExecFailure(['echo fnamemodify("file", v:null)'], 'E928:')
+   CheckDefExecFailure(['echo fnamemodify("file", "")'], 'E928:')
+ enddef
+ 
  def Test_filter_wrong_dict_key_type()
    assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
  enddef
***************
*** 313,318 ****
--- 358,387 ----
    d->assert_equal({items: []})
  enddef
  
+ def Test_getfperm()
+   CheckDefExecFailure(['echo getfperm(true)'], 'E928:')
+   CheckDefExecFailure(['echo getfperm(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo getfperm("")'], 'E928:')
+ enddef
+ 
+ def Test_getfsize()
+   CheckDefExecFailure(['echo getfsize(true)'], 'E928:')
+   CheckDefExecFailure(['echo getfsize(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo getfsize("")'], 'E928:')
+ enddef
+ 
+ def Test_getftime()
+   CheckDefExecFailure(['echo getftime(true)'], 'E928:')
+   CheckDefExecFailure(['echo getftime(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo getftime("")'], 'E928:')
+ enddef
+ 
+ def Test_getftype()
+   CheckDefExecFailure(['echo getftype(true)'], 'E928:')
+   CheckDefExecFailure(['echo getftype(v:null)'], 'E928:')
+   CheckDefExecFailure(['echo getftype("")'], 'E928:')
+ enddef
+ 
  def Test_getqflist_return_type()
    var l = getqflist()
    l->assert_equal([])
*** ../vim-8.2.2116/src/testdir/test_vim9_expr.vim      2020-12-07 
21:49:48.416837683 +0100
--- src/testdir/test_vim9_expr.vim      2020-12-09 12:39:02.918812498 +0100
***************
*** 1971,1977 ****
    CheckDefExecFailure(['var x: dict<string> = {a: "x", b: 134}'], 'E1012:', 1)
  
    CheckDefFailure(['var x = ({'], 'E723:', 2)
!   CheckDefExecFailure(['{}[getftype("")]'], 'E716: Key not present in 
Dictionary: ""', 1)
  enddef
  
  def Test_expr7_dict_vim9script()
--- 1971,1977 ----
    CheckDefExecFailure(['var x: dict<string> = {a: "x", b: 134}'], 'E1012:', 1)
  
    CheckDefFailure(['var x = ({'], 'E723:', 2)
!   CheckDefExecFailure(['{}[getftype("file")]'], 'E716: Key not present in 
Dictionary: ""', 1)
  enddef
  
  def Test_expr7_dict_vim9script()
*** ../vim-8.2.2116/src/version.c       2020-12-09 12:01:00.173093519 +0100
--- src/version.c       2020-12-09 12:39:39.670677447 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2117,
  /**/

-- 
Close your shells, or I'll kill -9 you
Tomorrow I'll quota you
Remember the disks'll always be full
And then while I'm away
I'll write ~ everyday
And I'll send-pr all my buggings to you.
    [ CVS log "Beatles style" for FreeBSD ports/INDEX, Satoshi Asami ]

 /// 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/202012091142.0B9BgL5p1888832%40masaka.moolenaar.net.

Raspunde prin e-mail lui