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 -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///