Skip to content

Commit cd91720

Browse files
yegappanbrammool
authored andcommitted
patch 8.2.3194: 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, simplify some. (Yegappan Lakshmanan, closes #8598)
1 parent 189663b commit cd91720

File tree

10 files changed

+253
-139
lines changed

10 files changed

+253
-139
lines changed

src/diff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3294,7 +3294,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
32943294
int col;
32953295

32963296
if (in_vim9script()
3297-
&& (check_for_string_or_number_arg(argvars,0) == FAIL
3297+
&& (check_for_lnum_arg(argvars,0) == FAIL
32983298
|| check_for_number_arg(argvars, 1) == FAIL))
32993299
return;
33003300

src/evalbuffer.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ f_bufnr(typval_T *argvars, typval_T *rettv)
388388
char_u *name;
389389

390390
if (in_vim9script()
391-
&& (check_for_opt_string_or_number_arg(argvars, 0) == FAIL
391+
&& (check_for_opt_buffer_arg(argvars, 0) == FAIL
392392
|| (argvars[0].v_type != VAR_UNKNOWN
393393
&& check_for_opt_bool_arg(argvars, 1) == FAIL)))
394394
return;
@@ -635,6 +635,11 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
635635
if (rettv_list_alloc(rettv) != OK)
636636
return;
637637

638+
if (in_vim9script()
639+
&& argvars[0].v_type != VAR_UNKNOWN
640+
&& check_for_buffer_or_dict_arg(argvars, 0) == FAIL)
641+
return;
642+
638643
// List of all the buffers or selected buffers
639644
if (argvars[0].v_type == VAR_DICT)
640645
{
@@ -774,6 +779,11 @@ f_getline(typval_T *argvars, typval_T *rettv)
774779
linenr_T end;
775780
int retlist;
776781

782+
if (in_vim9script()
783+
&& (check_for_lnum_arg(argvars, 0) == FAIL
784+
|| check_for_opt_lnum_arg(argvars, 1) == FAIL))
785+
return;
786+
777787
lnum = tv_get_lnum(argvars);
778788
if (argvars[1].v_type == VAR_UNKNOWN)
779789
{

src/evalfunc.c

Lines changed: 115 additions & 92 deletions
Large diffs are not rendered by default.

src/job.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1726,7 +1726,7 @@ f_prompt_setprompt(typval_T *argvars, typval_T *rettv UNUSED)
17261726
char_u *text;
17271727

17281728
if (in_vim9script()
1729-
&& (check_for_string_or_number_arg(argvars, 0) == FAIL
1729+
&& (check_for_buffer_arg(argvars, 0) == FAIL
17301730
|| check_for_string_arg(argvars, 1) == FAIL))
17311731
return;
17321732

src/proto/typval.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ int check_for_chan_or_job_arg(typval_T *args, int idx);
2525
int check_for_job_arg(typval_T *args, int idx);
2626
int check_for_string_or_number_arg(typval_T *args, int idx);
2727
int check_for_buffer_arg(typval_T *args, int idx);
28+
int check_for_opt_buffer_arg(typval_T *args, int idx);
2829
int check_for_lnum_arg(typval_T *args, int idx);
2930
int check_for_opt_lnum_arg(typval_T *args, int idx);
3031
int check_for_opt_string_or_number_arg(typval_T *args, int idx);
3132
int check_for_string_or_blob_arg(typval_T *args, int idx);
33+
int check_for_string_or_list_arg(typval_T *args, int idx);
34+
int check_for_buffer_or_dict_arg(typval_T *args, int idx);
3235
char_u *tv_get_string(typval_T *varp);
3336
char_u *tv_get_string_strict(typval_T *varp);
3437
char_u *tv_get_string_buf(typval_T *varp, char_u *buf);

src/sign.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2301,7 +2301,7 @@ f_sign_getplaced(typval_T *argvars, typval_T *rettv)
23012301
return;
23022302

23032303
if (in_vim9script()
2304-
&& (check_for_opt_string_or_number_arg(argvars, 0) == FAIL
2304+
&& (check_for_opt_buffer_arg(argvars, 0) == FAIL
23052305
|| (argvars[0].v_type != VAR_UNKNOWN
23062306
&& check_for_opt_dict_arg(argvars, 1) == FAIL)))
23072307
return;

src/terminal.c

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5779,11 +5779,18 @@ get_row_number(typval_T *tv, term_T *term)
57795779
void
57805780
f_term_getline(typval_T *argvars, typval_T *rettv)
57815781
{
5782-
buf_T *buf = term_get_buf(argvars, "term_getline()");
5782+
buf_T *buf;
57835783
term_T *term;
57845784
int row;
57855785

57865786
rettv->v_type = VAR_STRING;
5787+
5788+
if (in_vim9script()
5789+
&& (check_for_buffer_arg(argvars, 0) == FAIL
5790+
|| check_for_lnum_arg(argvars, 1) == FAIL))
5791+
return;
5792+
5793+
buf = term_get_buf(argvars, "term_getline()");
57875794
if (buf == NULL)
57885795
return;
57895796
term = buf->b_term;
@@ -5858,10 +5865,17 @@ f_term_getsize(typval_T *argvars, typval_T *rettv)
58585865
void
58595866
f_term_setsize(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
58605867
{
5861-
buf_T *buf = term_get_buf(argvars, "term_setsize()");
5868+
buf_T *buf;
58625869
term_T *term;
58635870
varnumber_T rows, cols;
58645871

5872+
if (in_vim9script()
5873+
&& (check_for_buffer_arg(argvars, 0) == FAIL
5874+
|| check_for_number_arg(argvars, 1) == FAIL
5875+
|| check_for_number_arg(argvars, 2) == FAIL))
5876+
return;
5877+
5878+
buf = term_get_buf(argvars, "term_setsize()");
58655879
if (buf == NULL)
58665880
{
58675881
emsg(_("E955: Not a terminal buffer"));
@@ -5933,7 +5947,7 @@ f_term_gettty(typval_T *argvars, typval_T *rettv)
59335947
int num = 0;
59345948

59355949
if (in_vim9script()
5936-
&& (check_for_string_or_number_arg(argvars, 0) == FAIL
5950+
&& (check_for_buffer_arg(argvars, 0) == FAIL
59375951
|| check_for_opt_bool_arg(argvars, 1) == FAIL))
59385952
return;
59395953

@@ -5988,7 +6002,7 @@ f_term_list(typval_T *argvars UNUSED, typval_T *rettv)
59886002
void
59896003
f_term_scrape(typval_T *argvars, typval_T *rettv)
59906004
{
5991-
buf_T *buf = term_get_buf(argvars, "term_scrape()");
6005+
buf_T *buf;
59926006
VTermScreen *screen = NULL;
59936007
VTermPos pos;
59946008
list_T *l;
@@ -5998,6 +6012,13 @@ f_term_scrape(typval_T *argvars, typval_T *rettv)
59986012

59996013
if (rettv_list_alloc(rettv) == FAIL)
60006014
return;
6015+
6016+
if (in_vim9script()
6017+
&& (check_for_buffer_arg(argvars, 0) == FAIL
6018+
|| check_for_lnum_arg(argvars, 1) == FAIL))
6019+
return;
6020+
6021+
buf = term_get_buf(argvars, "term_scrape()");
60016022
if (buf == NULL)
60026023
return;
60036024
term = buf->b_term;
@@ -6104,7 +6125,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv UNUSED)
61046125
term_T *term;
61056126

61066127
if (in_vim9script()
6107-
&& (check_for_string_or_number_arg(argvars, 0) == FAIL
6128+
&& (check_for_buffer_arg(argvars, 0) == FAIL
61086129
|| check_for_string_arg(argvars, 1) == FAIL))
61096130
return;
61106131

@@ -6183,7 +6204,7 @@ f_term_setansicolors(typval_T *argvars, typval_T *rettv UNUSED)
61836204
term_T *term;
61846205

61856206
if (in_vim9script()
6186-
&& (check_for_opt_string_or_number_arg(argvars, 0) == FAIL
6207+
&& (check_for_opt_buffer_arg(argvars, 0) == FAIL
61876208
|| (argvars[0].v_type != VAR_UNKNOWN
61886209
&& check_for_opt_list_arg(argvars, 1) == FAIL)))
61896210
return;
@@ -6217,7 +6238,7 @@ f_term_setapi(typval_T *argvars, typval_T *rettv UNUSED)
62176238
char_u *api;
62186239

62196240
if (in_vim9script()
6220-
&& (check_for_string_or_number_arg(argvars, 0) == FAIL
6241+
&& (check_for_buffer_arg(argvars, 0) == FAIL
62216242
|| check_for_string_arg(argvars, 1) == FAIL))
62226243
return;
62236244

@@ -6245,7 +6266,7 @@ f_term_setrestore(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
62456266
char_u *cmd;
62466267

62476268
if (in_vim9script()
6248-
&& (check_for_string_or_number_arg(argvars, 0) == FAIL
6269+
&& (check_for_buffer_arg(argvars, 0) == FAIL
62496270
|| check_for_string_arg(argvars, 1) == FAIL))
62506271
return;
62516272

@@ -6273,7 +6294,7 @@ f_term_setkill(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
62736294
char_u *how;
62746295

62756296
if (in_vim9script()
6276-
&& (check_for_string_or_number_arg(argvars, 0) == FAIL
6297+
&& (check_for_buffer_arg(argvars, 0) == FAIL
62776298
|| check_for_string_arg(argvars, 1) == FAIL))
62786299
return;
62796300

@@ -6298,6 +6319,11 @@ f_term_start(typval_T *argvars, typval_T *rettv)
62986319
jobopt_T opt;
62996320
buf_T *buf;
63006321

6322+
if (in_vim9script()
6323+
&& (check_for_string_or_list_arg(argvars, 0) == FAIL
6324+
|| check_for_opt_dict_arg(argvars, 1) == FAIL))
6325+
return;
6326+
63016327
init_job_options(&opt);
63026328
if (argvars[1].v_type != VAR_UNKNOWN
63036329
&& get_job_options(&argvars[1], &opt,
@@ -6326,7 +6352,7 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
63266352
buf_T *buf;
63276353

63286354
if (in_vim9script()
6329-
&& (check_for_string_or_number_arg(argvars, 0) == FAIL
6355+
&& (check_for_buffer_arg(argvars, 0) == FAIL
63306356
|| check_for_opt_number_arg(argvars, 1) == FAIL))
63316357
return;
63326358

src/testdir/test_vim9_builtin.vim

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,8 @@ def Test_cursor()
652652
assert_equal(2, getcurpos()[1])
653653
cursor('$', 1)
654654
assert_equal(4, getcurpos()[1])
655+
cursor([2, 1])
656+
assert_equal(2, getcurpos()[1])
655657

656658
var lines =<< trim END
657659
cursor('2', 1)
@@ -1105,6 +1107,7 @@ def Test_getbufinfo()
11051107
getbufinfo({bufloaded: true, buflisted: true, bufmodified: false})
11061108
->len()->assert_equal(3)
11071109
bwipe Xtestfile1 Xtestfile2
1110+
CheckDefAndScriptFailure2(['getbufinfo(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
11081111
enddef
11091112

11101113
def Test_getbufline()
@@ -1246,6 +1249,8 @@ def Test_getline()
12461249
echo getline('1')
12471250
END
12481251
CheckDefExecAndScriptFailure(lines, 'E1209:')
1252+
CheckDefAndScriptFailure2(['getline(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
1253+
CheckDefAndScriptFailure2(['getline(1, true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2')
12491254
enddef
12501255

12511256
def Test_getloclist()
@@ -3066,6 +3071,12 @@ def Test_term_getjob()
30663071
CheckDefAndScriptFailure2(['term_getjob(0z10)'], 'E1013: Argument 1: type mismatch, expected string but got blob', 'E974: Using a Blob as a Number')
30673072
enddef
30683073

3074+
def Test_term_getline()
3075+
CheckRunVimInTerminal
3076+
CheckDefAndScriptFailure2(['term_getline(1.1, 1)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1')
3077+
CheckDefAndScriptFailure2(['term_getline(1, 1.1)'], 'E1013: Argument 2: type mismatch, expected string but got float', 'E1174: String required for argument 2')
3078+
enddef
3079+
30693080
def Test_term_getscrolled()
30703081
CheckRunVimInTerminal
30713082
CheckDefAndScriptFailure2(['term_getscrolled(1.1)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E805: Using a Float as a Number')
@@ -3098,6 +3109,12 @@ def Test_term_gettty()
30983109
CheckDefAndScriptFailure2(['term_gettty(1, 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
30993110
enddef
31003111

3112+
def Test_term_scrape()
3113+
CheckRunVimInTerminal
3114+
CheckDefAndScriptFailure2(['term_scrape(1.1, 1)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1')
3115+
CheckDefAndScriptFailure2(['term_scrape(1, 1.1)'], 'E1013: Argument 2: type mismatch, expected string but got float', 'E1174: String required for argument 2')
3116+
enddef
3117+
31013118
def Test_term_sendkeys()
31023119
CheckRunVimInTerminal
31033120
CheckDefAndScriptFailure2(['term_sendkeys([], "p")'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
@@ -3127,6 +3144,14 @@ def Test_term_setrestore()
31273144
CheckDefAndScriptFailure2(['term_setrestore([], "p")'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
31283145
CheckDefAndScriptFailure2(['term_setrestore(1, [])'], 'E1013: Argument 2: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 2')
31293146
enddef
3147+
3148+
def Test_term_setsize()
3149+
CheckRunVimInTerminal
3150+
CheckDefAndScriptFailure2(['term_setsize(1.1, 2, 3)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1')
3151+
CheckDefAndScriptFailure2(['term_setsize(1, "2", 3)'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
3152+
CheckDefAndScriptFailure2(['term_setsize(1, 2, "3")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
3153+
enddef
3154+
31303155
def Test_term_start()
31313156
if !has('terminal')
31323157
CheckFeature terminal
@@ -3137,6 +3162,9 @@ def Test_term_start()
31373162
winnr()->assert_equal(winnr)
31383163
bwipe!
31393164
endif
3165+
CheckDefAndScriptFailure2(['term_start({})'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>', 'E1174: String required for argument 1')
3166+
CheckDefAndScriptFailure2(['term_start([], [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 2')
3167+
CheckDefAndScriptFailure2(['term_start("", "")'], 'E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E1206: Dictionary required for argument 2')
31403168
enddef
31413169

31423170
def Test_term_wait()

0 commit comments

Comments
 (0)