Skip to content

Commit 5b73992

Browse files
yegappanbrammool
authored andcommitted
patch 8.2.3135: Vim9: builtin function arguments not checked at compile time
Problem: Vim9: builtin function arguments not checked at compile time. Solution: Add more type checks. (Yegappan Lakshmanan, closes #8539)
1 parent 9da32e4 commit 5b73992

12 files changed

Lines changed: 563 additions & 186 deletions

File tree

src/channel.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,11 @@ channel_open_func(typval_T *argvars)
13111311
jobopt_T opt;
13121312
channel_T *channel = NULL;
13131313

1314+
if (in_vim9script()
1315+
&& (check_for_string_arg(argvars, 0) == FAIL
1316+
|| check_for_dict_arg(argvars, 1) == FAIL))
1317+
return NULL;
1318+
13141319
address = tv_get_string(&argvars[0]);
13151320
if (argvars[1].v_type != VAR_UNKNOWN
13161321
&& (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL))

src/errors.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,5 @@ EXTERN char e_regexp_number_after_dot_pos_search[]
492492
INIT(= N_("E1204: No Number allowed after .: '\\%%%c'"));
493493
EXTERN char e_no_white_space_allowed_between_option_and[]
494494
INIT(= N_("E1205: No white space allowed between option and"));
495+
EXTERN char e_dict_required_for_argument_nr[]
496+
INIT(= N_("E1206: Dictionary required for argument %d"));

src/evalfunc.c

Lines changed: 94 additions & 70 deletions
Large diffs are not rendered by default.

src/proto/typval.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ varnumber_T tv_get_bool_chk(typval_T *varp, int *denote);
1111
float_T tv_get_float(typval_T *varp);
1212
int check_for_string_arg(typval_T *args, int idx);
1313
int check_for_nonempty_string_arg(typval_T *args, int idx);
14+
int check_for_dict_arg(typval_T *args, int idx);
1415
char_u *tv_get_string(typval_T *varp);
1516
char_u *tv_get_string_strict(typval_T *varp);
1617
char_u *tv_get_string_buf(typval_T *varp, char_u *buf);

src/terminal.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5276,6 +5276,11 @@ term_load_dump(typval_T *argvars, typval_T *rettv, int do_diff)
52765276
FILE *fd2 = NULL;
52775277
char_u *textline = NULL;
52785278

5279+
if (in_vim9script()
5280+
&& (check_for_string_arg(argvars, 0) == FAIL
5281+
|| check_for_dict_arg(argvars, 1) == FAIL))
5282+
return;
5283+
52795284
// First open the files. If this fails bail out.
52805285
fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
52815286
if (do_diff)

src/testdir/test_search.vim

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,9 @@ func Test_searchpairpos()
373373
endfunc
374374

375375
func Test_searchpair_errors()
376-
call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String')
377-
call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
378-
call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
376+
call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
377+
call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
378+
call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String')
379379
call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
380380
call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
381381
call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
@@ -384,9 +384,9 @@ func Test_searchpair_errors()
384384
endfunc
385385

386386
func Test_searchpairpos_errors()
387-
call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String')
388-
call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
389-
call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
387+
call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
388+
call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
389+
call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String')
390390
call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
391391
call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
392392
call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')

src/testdir/test_textprop.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ endfunc
13401340
func Test_prop_func_invalid_args()
13411341
call assert_fails('call prop_clear(1, 2, [])', 'E715:')
13421342
call assert_fails('call prop_clear(-1, 2)', 'E16:')
1343-
call assert_fails('call prop_find(test_null_dict())', 'E474:')
1343+
call assert_fails('call prop_find(test_null_dict())', 'E715:')
13441344
call assert_fails('call prop_find({"bufnr" : []})', 'E730:')
13451345
call assert_fails('call prop_find({})', 'E968:')
13461346
call assert_fails('call prop_find({}, "x")', 'E474:')

src/testdir/test_vim9_builtin.vim

Lines changed: 421 additions & 103 deletions
Large diffs are not rendered by default.

src/testing.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,10 @@ f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10961096
void
10971097
f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
10981098
{
1099-
ignore_error_for_testing(tv_get_string(&argvars[0]));
1099+
if (argvars[0].v_type != VAR_STRING)
1100+
emsg(_(e_invarg));
1101+
else
1102+
ignore_error_for_testing(tv_get_string(&argvars[0]));
11001103
}
11011104

11021105
void

src/textprop.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ f_prop_find(typval_T *argvars, typval_T *rettv)
605605

606606
if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL)
607607
{
608-
emsg(_(e_invarg));
608+
emsg(_(e_dictreq));
609609
return;
610610
}
611611
dict = argvars[0].vval.v_dict;

0 commit comments

Comments
 (0)