Skip to content

Commit 0ad871d

Browse files
yegappanbrammool
authored andcommitted
patch 8.2.3206: 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. (Yegappan Lakshmanan, closes #8611)
1 parent 1b862c4 commit 0ad871d

19 files changed

Lines changed: 456 additions & 152 deletions

src/blob.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,12 +418,6 @@ blob_remove(typval_T *argvars, typval_T *rettv)
418418
long idx;
419419
long end;
420420

421-
if (in_vim9script()
422-
&& (check_for_blob_arg(argvars, 0) == FAIL
423-
|| check_for_number_arg(argvars, 1) == FAIL
424-
|| check_for_opt_number_arg(argvars, 2) == FAIL))
425-
return;
426-
427421
idx = (long)tv_get_number_chk(&argvars[1], &error);
428422
if (!error)
429423
{

src/cmdhist.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,11 @@ f_histdel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
570570
char_u buf[NUMBUFLEN];
571571
char_u *str;
572572

573+
if (in_vim9script()
574+
&& (check_for_string_arg(argvars, 0) == FAIL
575+
|| check_for_opt_string_or_number_arg(argvars, 1) == FAIL))
576+
return;
577+
573578
str = tv_get_string_chk(&argvars[0]); // NULL on type error
574579
if (str == NULL)
575580
n = 0;

src/dict.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,11 +1340,6 @@ dict_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
13401340
char_u *key;
13411341
dictitem_T *di;
13421342

1343-
if (in_vim9script()
1344-
&& (check_for_dict_arg(argvars, 0) == FAIL
1345-
|| check_for_string_or_number_arg(argvars, 1) == FAIL))
1346-
return;
1347-
13481343
if (argvars[2].v_type != VAR_UNKNOWN)
13491344
semsg(_(e_toomanyarg), "remove()");
13501345
else if ((d = argvars[0].vval.v_dict) != NULL

src/errors.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,7 @@ EXTERN char e_digraph_argument_must_be_one_character_str[]
613613
EXTERN char e_setdigraphlist_argument_must_be_list_of_lists_with_two_items[]
614614
INIT(= N_("E1216: setdigraphlist() argument must be a list of lists with two items"));
615615
#endif
616-
EXTERN char e_blob_required_for_argument_nr[]
617-
INIT(= N_("E1217: Blob required for argument %d"));
618616
EXTERN char e_chan_or_job_required_for_argument_nr[]
619-
INIT(= N_("E1218: Channel or Job required for argument %d"));
617+
INIT(= N_("E1217: Channel or Job required for argument %d"));
620618
EXTERN char e_job_required_for_argument_nr[]
621-
INIT(= N_("E1219: Job required for argument %d"));
619+
INIT(= N_("E1218: Job required for argument %d"));

src/evalfunc.c

Lines changed: 138 additions & 82 deletions
Large diffs are not rendered by default.

src/filepath.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,12 @@ f_writefile(typval_T *argvars, typval_T *rettv)
21802180
if (check_secure())
21812181
return;
21822182

2183+
if (in_vim9script()
2184+
&& (check_for_list_or_blob_arg(argvars, 0) == FAIL
2185+
|| check_for_string_arg(argvars, 1) == FAIL
2186+
|| check_for_opt_string_arg(argvars, 2) == FAIL))
2187+
return;
2188+
21832189
if (argvars[0].v_type == VAR_LIST)
21842190
{
21852191
list = argvars[0].vval.v_list;

src/globals.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1673,7 +1673,6 @@ EXTERN char e_boolreq[] INIT(= N_("E839: Bool required"));
16731673
EXTERN char e_emptykey[] INIT(= N_("E713: Cannot use empty key for Dictionary"));
16741674
EXTERN char e_dictreq[] INIT(= N_("E715: Dictionary required"));
16751675
EXTERN char e_listidx[] INIT(= N_("E684: list index out of range: %ld"));
1676-
EXTERN char e_blobreq[] INIT(= N_("E538: Dictionary required"));
16771676
EXTERN char e_blobidx[] INIT(= N_("E979: Blob index out of range: %ld"));
16781677
EXTERN char e_invalblob[] INIT(= N_("E978: Invalid operation for Blob"));
16791678
EXTERN char e_toomanyarg[] INIT(= N_("E118: Too many arguments for function: %s"));

src/job.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,12 @@ f_job_start(typval_T *argvars, typval_T *rettv)
18991899
rettv->v_type = VAR_JOB;
19001900
if (check_restricted() || check_secure())
19011901
return;
1902+
1903+
if (in_vim9script()
1904+
&& (check_for_string_or_list_arg(argvars, 0) == FAIL
1905+
|| check_for_opt_dict_arg(argvars, 1) == FAIL))
1906+
return;
1907+
19021908
rettv->vval.v_job = job_start(argvars, NULL, NULL, NULL);
19031909
}
19041910

src/list.c

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,12 +1540,6 @@ list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
15401540
int error = FALSE;
15411541
long idx;
15421542

1543-
if (in_vim9script()
1544-
&& (check_for_list_arg(argvars, 0) == FAIL
1545-
|| check_for_number_arg(argvars, 1) == FAIL
1546-
|| check_for_opt_number_arg(argvars, 2) == FAIL))
1547-
return;
1548-
15491543
if ((l = argvars[0].vval.v_list) == NULL
15501544
|| value_check_lock(l->lv_lock, arg_errmsg, TRUE))
15511545
return;
@@ -1806,6 +1800,12 @@ do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
18061800
long len;
18071801
long i;
18081802

1803+
if (in_vim9script()
1804+
&& (check_for_list_arg(argvars, 0) == FAIL
1805+
|| (argvars[1].v_type != VAR_UNKNOWN
1806+
&& check_for_opt_dict_arg(argvars, 2) == FAIL)))
1807+
return;
1808+
18091809
// Pointer to current info struct used in compare function. Save and
18101810
// restore the current one for nested calls.
18111811
old_sortinfo = sortinfo;
@@ -2103,6 +2103,11 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
21032103
// map() and filter() return the first argument, also on failure.
21042104
if (filtermap != FILTERMAP_MAPNEW)
21052105
copy_tv(&argvars[0], rettv);
2106+
2107+
if (in_vim9script()
2108+
&& (check_for_list_or_dict_or_blob_arg(argvars, 0) == FAIL))
2109+
return;
2110+
21062111
if (filtermap == FILTERMAP_MAP && in_vim9script())
21072112
{
21082113
// Check that map() does not change the type of the dict.
@@ -2463,6 +2468,13 @@ f_mapnew(typval_T *argvars, typval_T *rettv)
24632468
f_add(typval_T *argvars, typval_T *rettv)
24642469
{
24652470
rettv->vval.v_number = 1; // Default: Failed
2471+
2472+
if (in_vim9script()
2473+
&& (check_for_list_or_blob_arg(argvars, 0) == FAIL
2474+
|| (argvars[0].v_type == VAR_BLOB
2475+
&& check_for_number_arg(argvars, 1) == FAIL)))
2476+
return;
2477+
24662478
if (argvars[0].v_type == VAR_LIST)
24672479
{
24682480
list_T *l = argvars[0].vval.v_list;
@@ -2799,6 +2811,13 @@ f_insert(typval_T *argvars, typval_T *rettv)
27992811
listitem_T *item;
28002812
int error = FALSE;
28012813

2814+
if (in_vim9script()
2815+
&& (check_for_list_or_blob_arg(argvars, 0) == FAIL
2816+
|| (argvars[0].v_type == VAR_BLOB
2817+
&& check_for_number_arg(argvars, 1) == FAIL)
2818+
|| check_for_opt_number_arg(argvars, 2) == FAIL))
2819+
return;
2820+
28022821
if (argvars[0].v_type == VAR_BLOB)
28032822
{
28042823
int val, len;
@@ -2888,6 +2907,16 @@ f_remove(typval_T *argvars, typval_T *rettv)
28882907
{
28892908
char_u *arg_errmsg = (char_u *)N_("remove() argument");
28902909

2910+
if (in_vim9script()
2911+
&& (check_for_list_or_dict_or_blob_arg(argvars, 0) == FAIL
2912+
|| ((argvars[0].v_type == VAR_LIST
2913+
|| argvars[0].v_type == VAR_BLOB)
2914+
&& (check_for_number_arg(argvars, 1) == FAIL
2915+
|| check_for_opt_number_arg(argvars, 2) == FAIL))
2916+
|| (argvars[0].v_type == VAR_DICT
2917+
&& check_for_string_or_number_arg(argvars, 1) == FAIL)))
2918+
return;
2919+
28912920
if (argvars[0].v_type == VAR_DICT)
28922921
dict_remove(argvars, rettv, arg_errmsg);
28932922
else if (argvars[0].v_type == VAR_BLOB)
@@ -2907,6 +2936,9 @@ f_reverse(typval_T *argvars, typval_T *rettv)
29072936
list_T *l;
29082937
listitem_T *li, *ni;
29092938

2939+
if (in_vim9script() && check_for_list_or_blob_arg(argvars, 0) == FAIL)
2940+
return;
2941+
29102942
if (argvars[0].v_type == VAR_BLOB)
29112943
{
29122944
blob_T *b = argvars[0].vval.v_blob;

src/match.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,8 +1163,8 @@ f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
11631163
{
11641164
# ifdef FEAT_SEARCH_EXTRA
11651165
char_u buf[NUMBUFLEN];
1166-
char_u *grp = tv_get_string_buf_chk(&argvars[0], buf); // group
1167-
char_u *pat = tv_get_string_buf_chk(&argvars[1], buf); // pattern
1166+
char_u *grp; // group
1167+
char_u *pat; // pattern
11681168
int prio = 10; // default priority
11691169
int id = -1;
11701170
int error = FALSE;
@@ -1173,6 +1173,18 @@ f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
11731173

11741174
rettv->vval.v_number = -1;
11751175

1176+
if (in_vim9script()
1177+
&& (check_for_string_arg(argvars, 0) == FAIL
1178+
|| check_for_string_arg(argvars, 1) == FAIL
1179+
|| check_for_opt_number_arg(argvars, 2) == FAIL
1180+
|| (argvars[2].v_type != VAR_UNKNOWN
1181+
&& (check_for_opt_number_arg(argvars, 3) == FAIL
1182+
|| (argvars[3].v_type != VAR_UNKNOWN
1183+
&& check_for_opt_dict_arg(argvars, 4) == FAIL)))))
1184+
return;
1185+
1186+
grp = tv_get_string_buf_chk(&argvars[0], buf); // group
1187+
pat = tv_get_string_buf_chk(&argvars[1], buf); // pattern
11761188
if (grp == NULL || pat == NULL)
11771189
return;
11781190
if (argvars[2].v_type != VAR_UNKNOWN)
@@ -1217,6 +1229,16 @@ f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
12171229

12181230
rettv->vval.v_number = -1;
12191231

1232+
if (in_vim9script()
1233+
&& (check_for_string_arg(argvars, 0) == FAIL
1234+
|| check_for_list_arg(argvars, 1) == FAIL
1235+
|| check_for_opt_number_arg(argvars, 2) == FAIL
1236+
|| (argvars[2].v_type != VAR_UNKNOWN
1237+
&& (check_for_opt_number_arg(argvars, 3) == FAIL
1238+
|| (argvars[3].v_type != VAR_UNKNOWN
1239+
&& check_for_opt_dict_arg(argvars, 4) == FAIL)))))
1240+
return;
1241+
12201242
group = tv_get_string_buf_chk(&argvars[0], buf);
12211243
if (group == NULL)
12221244
return;

0 commit comments

Comments
 (0)