To: vim_dev@googlegroups.com Subject: Patch 8.2.2664 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@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 ///