Skip to content

Commit 7973de3

Browse files
yegappanbrammool
authored andcommitted
patch 8.2.3211: Vim9: argument types are not checked at compile time
Problem: Vim9: argument types are not checked at compile time. Solution: Add several more type checks. Fix type check for matchaddpos(). (Yegappan Lakshmanan, closes #8619)
1 parent dd0b287 commit 7973de3

10 files changed

Lines changed: 165 additions & 22 deletions

File tree

src/channel.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4890,9 +4890,15 @@ f_ch_info(typval_T *argvars, typval_T *rettv UNUSED)
48904890
void
48914891
f_ch_log(typval_T *argvars, typval_T *rettv UNUSED)
48924892
{
4893-
char_u *msg = tv_get_string(&argvars[0]);
4893+
char_u *msg;
48944894
channel_T *channel = NULL;
48954895

4896+
if (in_vim9script()
4897+
&& (check_for_string_arg(argvars, 0) == FAIL
4898+
|| check_for_opt_chan_or_job_arg(argvars, 1) == FAIL))
4899+
return;
4900+
4901+
msg = tv_get_string(&argvars[0]);
48964902
if (argvars[1].v_type != VAR_UNKNOWN)
48974903
channel = get_channel_arg(&argvars[1], FALSE, FALSE, 0);
48984904

src/evalfunc.c

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,8 @@ arg_dict_any_or_string(type_T *type, argcontext_T *context)
542542
}
543543

544544
/*
545-
* Check "type" which is the third argument of extend().
545+
* Check "type" which is the third argument of extend() (number or string or
546+
* any)
546547
*/
547548
static int
548549
arg_extend3(type_T *type, argcontext_T *context)
@@ -557,7 +558,8 @@ arg_extend3(type_T *type, argcontext_T *context)
557558
}
558559

559560
/*
560-
* Check "type" which is the second argument of remove().
561+
* Check "type" which is the second argument of remove() (number or string or
562+
* any)
561563
*/
562564
static int
563565
arg_remove2(type_T *type, argcontext_T *context)
@@ -572,7 +574,8 @@ arg_remove2(type_T *type, argcontext_T *context)
572574
}
573575

574576
/*
575-
* Check "type" which is the first argument of repeat().
577+
* Check "type" which is the first argument of repeat() (string or number or
578+
* list or any)
576579
*/
577580
static int
578581
arg_repeat1(type_T *type, argcontext_T *context)
@@ -588,7 +591,8 @@ arg_repeat1(type_T *type, argcontext_T *context)
588591
}
589592

590593
/*
591-
* Check "type" which is the first argument of slice().
594+
* Check "type" which is the first argument of slice() (list or blob or string
595+
* or any)
592596
*/
593597
static int
594598
arg_slice1(type_T *type, argcontext_T *context)
@@ -604,7 +608,8 @@ arg_slice1(type_T *type, argcontext_T *context)
604608
}
605609

606610
/*
607-
* Check "type" which is the first argument of count().
611+
* Check "type" which is the first argument of count() (string or list or dict
612+
* or any)
608613
*/
609614
static int
610615
arg_count1(type_T *type, argcontext_T *context)
@@ -620,7 +625,8 @@ arg_count1(type_T *type, argcontext_T *context)
620625
}
621626

622627
/*
623-
* Check "type" which is the first argument of cursor().
628+
* Check "type" which is the first argument of cursor() (number or string or
629+
* list or any)
624630
*/
625631
static int
626632
arg_cursor1(type_T *type, argcontext_T *context)
@@ -666,6 +672,7 @@ static argcheck_T arg2_string_list_nr[] = {arg_string, arg_list_number};
666672
static argcheck_T arg2_string_bool[] = {arg_string, arg_bool};
667673
static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
668674
static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr};
675+
static argcheck_T arg2_string_chan_or_job[] = {arg_string, arg_chan_or_job};
669676
static argcheck_T arg2_list_number[] = {arg_list_number, arg_list_number};
670677
static argcheck_T arg2_list_number_bool[] = {arg_list_number, arg_bool};
671678
static argcheck_T arg2_list_any_string[] = {arg_list_any, arg_string};
@@ -690,11 +697,14 @@ static argcheck_T arg2_buffer_number[] = {arg_buffer, arg_number};
690697
static argcheck_T arg2_buffer_bool[] = {arg_buffer, arg_bool};
691698
static argcheck_T arg2_buffer_lnum[] = {arg_buffer, arg_lnum};
692699
static argcheck_T arg2_buffer_list_any[] = {arg_buffer, arg_list_any};
700+
static argcheck_T arg2_buffer_any[] = {arg_buffer, NULL};
693701
static argcheck_T arg3_string[] = {arg_string, arg_string, arg_string};
694702
static argcheck_T arg3_number[] = {arg_number, arg_number, arg_number};
695703
static argcheck_T arg3_number_number_dict[] = {arg_number, arg_number, arg_dict_any};
704+
static argcheck_T arg3_number_string_string[] = {arg_number, arg_string, arg_string};
696705
static argcheck_T arg3_number_string_any[] = {arg_number, arg_string, NULL};
697706
static argcheck_T arg3_number_string_buffer[] = {arg_number, arg_string, arg_buffer};
707+
static argcheck_T arg3_number_any_dict[] = {arg_number, NULL, arg_dict_any};
698708
static argcheck_T arg3_string_nr_bool[] = {arg_string, arg_number, arg_bool};
699709
static argcheck_T arg3_string_string_nr[] = {arg_string, arg_string, arg_number};
700710
static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any};
@@ -707,6 +717,7 @@ static argcheck_T arg3_lnum_number_bool[] = {arg_lnum, arg_number, arg_bool};
707717
static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
708718
static argcheck_T arg3_buffer_number_number[] = {arg_buffer, arg_number, arg_number};
709719
static argcheck_T arg3_buffer_string_dict[] = {arg_buffer, arg_string, arg_dict_any};
720+
static argcheck_T arg3_buffer_string_any[] = {arg_buffer, arg_string, NULL};
710721
static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL};
711722
static argcheck_T arg4_string_string_number_string[] = {arg_string, arg_string, arg_number, arg_string};
712723
static argcheck_T arg5_number[] = {arg_number, arg_number, arg_number, arg_number, arg_number};
@@ -726,12 +737,13 @@ static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_numb
726737
static argcheck_T arg2_mapfilter[] = {arg_list_or_dict_or_blob, NULL};
727738
static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool};
728739
static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any};
729-
static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_number, arg_number, arg_number, arg_dict_any};
740+
static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any};
730741
static argcheck_T arg23_reduce[] = {arg_list_or_blob, NULL, NULL};
731742
static argcheck_T arg24_remote_expr[] = {arg_string, arg_string, arg_string, arg_number};
732743
static argcheck_T arg23_remove[] = {arg_list_or_dict_or_blob, arg_remove2, arg_number};
733744
static argcheck_T arg2_repeat[] = {arg_repeat1, arg_number};
734745
static argcheck_T arg15_search[] = {arg_string, arg_string, arg_number, arg_number, NULL};
746+
static argcheck_T arg37_searchpair[] = {arg_string, arg_string, arg_string, arg_string, NULL, arg_number, arg_number};
735747
static argcheck_T arg3_setbufline[] = {arg_buffer, arg_lnum, arg_str_or_nr_or_list};
736748
static argcheck_T arg2_setline[] = {arg_lnum, NULL};
737749
static argcheck_T arg24_setloclist[] = {arg_number, arg_list_any, arg_string, arg_dict_any};
@@ -1146,7 +1158,7 @@ static funcentry_T global_functions[] =
11461158
ret_job, JOB_FUNC(f_ch_getjob)},
11471159
{"ch_info", 1, 1, FEARG_1, arg1_chan_or_job,
11481160
ret_dict_any, JOB_FUNC(f_ch_info)},
1149-
{"ch_log", 1, 2, FEARG_1, NULL,
1161+
{"ch_log", 1, 2, FEARG_1, arg2_string_chan_or_job,
11501162
ret_void, JOB_FUNC(f_ch_log)},
11511163
{"ch_logfile", 1, 2, FEARG_1, arg2_string,
11521164
ret_void, JOB_FUNC(f_ch_logfile)},
@@ -1202,7 +1214,7 @@ static funcentry_T global_functions[] =
12021214
ret_float, FLOAT_FUNC(f_cosh)},
12031215
{"count", 2, 4, FEARG_1, arg24_count,
12041216
ret_number, f_count},
1205-
{"cscope_connection",0,3, 0, NULL,
1217+
{"cscope_connection",0,3, 0, arg3_number_string_string,
12061218
ret_number, f_cscope_connection},
12071219
{"cursor", 1, 3, FEARG_1, arg13_cursor,
12081220
ret_number, f_cursor},
@@ -1310,7 +1322,7 @@ static funcentry_T global_functions[] =
13101322
ret_list_dict_any, f_getbufinfo},
13111323
{"getbufline", 2, 3, FEARG_1, arg3_buffer_lnum_lnum,
13121324
ret_list_string, f_getbufline},
1313-
{"getbufvar", 2, 3, FEARG_1, NULL,
1325+
{"getbufvar", 2, 3, FEARG_1, arg3_buffer_string_any,
13141326
ret_any, f_getbufvar},
13151327
{"getchangelist", 0, 1, FEARG_1, arg1_buffer,
13161328
ret_list_any, f_getchangelist},
@@ -1650,9 +1662,9 @@ static funcentry_T global_functions[] =
16501662
ret_string, f_printf},
16511663
{"prompt_getprompt", 1, 1, FEARG_1, arg1_buffer,
16521664
ret_string, JOB_FUNC(f_prompt_getprompt)},
1653-
{"prompt_setcallback", 2, 2, FEARG_1, NULL,
1665+
{"prompt_setcallback", 2, 2, FEARG_1, arg2_buffer_any,
16541666
ret_void, JOB_FUNC(f_prompt_setcallback)},
1655-
{"prompt_setinterrupt", 2, 2, FEARG_1, NULL,
1667+
{"prompt_setinterrupt", 2, 2, FEARG_1, arg2_buffer_any,
16561668
ret_void, JOB_FUNC(f_prompt_setinterrupt)},
16571669
{"prompt_setprompt", 2, 2, FEARG_1, arg2_buffer_string,
16581670
ret_void, JOB_FUNC(f_prompt_setprompt)},
@@ -1780,9 +1792,9 @@ static funcentry_T global_functions[] =
17801792
ret_dict_any, f_searchcount},
17811793
{"searchdecl", 1, 3, FEARG_1, arg3_string_bool_bool,
17821794
ret_number_bool, f_searchdecl},
1783-
{"searchpair", 3, 7, 0, NULL,
1795+
{"searchpair", 3, 7, 0, arg37_searchpair,
17841796
ret_number, f_searchpair},
1785-
{"searchpairpos", 3, 7, 0, NULL,
1797+
{"searchpairpos", 3, 7, 0, arg37_searchpair,
17861798
ret_list_number, f_searchpairpos},
17871799
{"searchpos", 1, 5, FEARG_1, arg15_search,
17881800
ret_list_number, f_searchpos},
@@ -1792,7 +1804,7 @@ static funcentry_T global_functions[] =
17921804
ret_string, f_serverlist},
17931805
{"setbufline", 3, 3, FEARG_3, arg3_setbufline,
17941806
ret_number_bool, f_setbufline},
1795-
{"setbufvar", 3, 3, FEARG_3, NULL,
1807+
{"setbufvar", 3, 3, FEARG_3, arg3_buffer_string_any,
17961808
ret_void, f_setbufvar},
17971809
{"setcellwidths", 1, 1, FEARG_1, arg1_list_any,
17981810
ret_void, f_setcellwidths},
@@ -1950,7 +1962,7 @@ static funcentry_T global_functions[] =
19501962
ret_string, f_swapname},
19511963
{"synID", 3, 3, 0, arg3_lnum_number_bool,
19521964
ret_number, f_synID},
1953-
{"synIDattr", 2, 3, FEARG_1, NULL,
1965+
{"synIDattr", 2, 3, FEARG_1, arg3_number_string_string,
19541966
ret_string, f_synIDattr},
19551967
{"synIDtrans", 1, 1, FEARG_1, arg1_number,
19561968
ret_number, f_synIDtrans},
@@ -2102,7 +2114,7 @@ static funcentry_T global_functions[] =
21022114
ret_list_dict_any, TIMER_FUNC(f_timer_info)},
21032115
{"timer_pause", 2, 2, FEARG_1, arg2_number_bool,
21042116
ret_void, TIMER_FUNC(f_timer_pause)},
2105-
{"timer_start", 2, 3, FEARG_1, NULL,
2117+
{"timer_start", 2, 3, FEARG_1, arg3_number_any_dict,
21062118
ret_number, TIMER_FUNC(f_timer_start)},
21072119
{"timer_stop", 1, 1, FEARG_1, arg1_number,
21082120
ret_void, TIMER_FUNC(f_timer_stop)},
@@ -8044,6 +8056,18 @@ searchpair_cmn(typval_T *argvars, pos_T *match_pos)
80448056
long lnum_stop = 0;
80458057
long time_limit = 0;
80468058

8059+
if (in_vim9script()
8060+
&& (check_for_string_arg(argvars, 0) == FAIL
8061+
|| check_for_string_arg(argvars, 1) == FAIL
8062+
|| check_for_string_arg(argvars, 2) == FAIL
8063+
|| check_for_opt_string_arg(argvars, 3) == FAIL
8064+
|| (argvars[3].v_type != VAR_UNKNOWN
8065+
&& argvars[4].v_type != VAR_UNKNOWN
8066+
&& (check_for_opt_number_arg(argvars, 5) == FAIL
8067+
|| (argvars[5].v_type != VAR_UNKNOWN
8068+
&& check_for_opt_number_arg(argvars, 6) == FAIL)))))
8069+
goto theend;
8070+
80478071
// Get the three pattern arguments: start, middle, end. Will result in an
80488072
// error if not a valid argument.
80498073
spat = tv_get_string_chk(&argvars[0]);
@@ -9245,6 +9269,13 @@ f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
92459269
char_u modebuf[NUMBUFLEN];
92469270
int modec;
92479271

9272+
if (in_vim9script()
9273+
&& (check_for_number_arg(argvars, 0) == FAIL
9274+
|| (check_for_string_arg(argvars, 1) == FAIL
9275+
|| (argvars[1].v_type != VAR_UNKNOWN
9276+
&& check_for_opt_string_arg(argvars, 2) == FAIL))))
9277+
return;
9278+
92489279
id = (int)tv_get_number(&argvars[0]);
92499280
what = tv_get_string(&argvars[1]);
92509281
if (argvars[2].v_type != VAR_UNKNOWN)

src/evalvars.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4112,6 +4112,11 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
41124112
dictitem_T *v;
41134113
int done = FALSE;
41144114

4115+
if (in_vim9script()
4116+
&& (check_for_buffer_arg(argvars, 0) == FAIL
4117+
|| check_for_string_arg(argvars, 1) == FAIL))
4118+
return;
4119+
41154120
varname = tv_get_string_chk(&argvars[1]);
41164121
buf = tv_get_buf_from_arg(&argvars[0]);
41174122

@@ -4251,6 +4256,12 @@ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
42514256

42524257
if (check_secure())
42534258
return;
4259+
4260+
if (in_vim9script()
4261+
&& (check_for_buffer_arg(argvars, 0) == FAIL
4262+
|| check_for_string_arg(argvars, 1) == FAIL))
4263+
return;
4264+
42544265
varname = tv_get_string_chk(&argvars[1]);
42554266
buf = tv_get_buf_from_arg(&argvars[0]);
42564267
varp = &argvars[2];

src/if_cscope.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,6 +2496,14 @@ f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
24962496
char_u *prepend = NULL;
24972497
char_u buf[NUMBUFLEN];
24982498

2499+
if (in_vim9script()
2500+
&& (check_for_opt_number_arg(argvars, 0) == FAIL
2501+
|| (argvars[0].v_type != VAR_UNKNOWN
2502+
&& (check_for_opt_string_arg(argvars, 1) == FAIL
2503+
|| (argvars[1].v_type != VAR_UNKNOWN
2504+
&& check_for_opt_string_arg(argvars, 2) == FAIL)))))
2505+
return;
2506+
24992507
if (argvars[0].v_type != VAR_UNKNOWN
25002508
&& argvars[1].v_type != VAR_UNKNOWN)
25012509
{

src/job.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,10 @@ f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
16581658

16591659
if (check_secure())
16601660
return;
1661+
1662+
if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
1663+
return;
1664+
16611665
buf = tv_get_buf(&argvars[0], FALSE);
16621666
if (buf == NULL)
16631667
return;
@@ -1681,6 +1685,10 @@ f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
16811685

16821686
if (check_secure())
16831687
return;
1688+
1689+
if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
1690+
return;
1691+
16841692
buf = tv_get_buf(&argvars[0], FALSE);
16851693
if (buf == NULL)
16861694
return;

src/proto/typval.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ int check_for_opt_list_arg(typval_T *args, int idx);
2121
int check_for_dict_arg(typval_T *args, int idx);
2222
int check_for_opt_dict_arg(typval_T *args, int idx);
2323
int check_for_chan_or_job_arg(typval_T *args, int idx);
24+
int check_for_opt_chan_or_job_arg(typval_T *args, int idx);
2425
int check_for_job_arg(typval_T *args, int idx);
2526
int check_for_string_or_number_arg(typval_T *args, int idx);
2627
int check_for_buffer_arg(typval_T *args, int idx);

0 commit comments

Comments
 (0)