Skip to content

Commit 7bb4e74

Browse files
committed
patch 8.2.2117: some functions use any value as a string
Problem: Some functions use any value as a string. Solution: Check that the value is a non-empty string.
1 parent 2c78a77 commit 7bb4e74

7 files changed

Lines changed: 113 additions & 13 deletions

File tree

src/filepath.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -861,10 +861,11 @@ f_delete(typval_T *argvars, typval_T *rettv)
861861
void
862862
f_executable(typval_T *argvars, typval_T *rettv)
863863
{
864-
char_u *name = tv_get_string(&argvars[0]);
864+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
865+
return;
865866

866867
// Check in $PATH and also check directly if there is a directory name.
867-
rettv->vval.v_number = mch_can_exe(name, NULL, TRUE);
868+
rettv->vval.v_number = mch_can_exe(tv_get_string(&argvars[0]), NULL, TRUE);
868869
}
869870

870871
/*
@@ -875,6 +876,8 @@ f_exepath(typval_T *argvars, typval_T *rettv)
875876
{
876877
char_u *p = NULL;
877878

879+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
880+
return;
878881
(void)mch_can_exe(tv_get_string(&argvars[0]), &p, TRUE);
879882
rettv->v_type = VAR_STRING;
880883
rettv->vval.v_string = p;
@@ -890,6 +893,8 @@ f_filereadable(typval_T *argvars, typval_T *rettv)
890893
char_u *p;
891894
int n;
892895

896+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
897+
return;
893898
#ifndef O_NONBLOCK
894899
# define O_NONBLOCK 0
895900
#endif
@@ -913,6 +918,8 @@ f_filereadable(typval_T *argvars, typval_T *rettv)
913918
void
914919
f_filewritable(typval_T *argvars, typval_T *rettv)
915920
{
921+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
922+
return;
916923
rettv->vval.v_number = filewritable(tv_get_string(&argvars[0]));
917924
}
918925

@@ -935,6 +942,8 @@ findfilendir(
935942

936943
rettv->vval.v_string = NULL;
937944
rettv->v_type = VAR_STRING;
945+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
946+
return;
938947

939948
#ifdef FEAT_SEARCHPATH
940949
fname = tv_get_string(&argvars[0]);
@@ -1014,6 +1023,9 @@ f_fnamemodify(typval_T *argvars, typval_T *rettv)
10141023
char_u *fbuf = NULL;
10151024
char_u buf[NUMBUFLEN];
10161025

1026+
if (in_vim9script() && (check_for_string(&argvars[0]) == FAIL
1027+
|| check_for_string(&argvars[1]) == FAIL))
1028+
return;
10171029
fname = tv_get_string_chk(&argvars[0]);
10181030
mods = tv_get_string_buf_chk(&argvars[1], buf);
10191031
if (fname == NULL || mods == NULL)
@@ -1122,6 +1134,8 @@ f_getfperm(typval_T *argvars, typval_T *rettv)
11221134
char_u *perm = NULL;
11231135
char_u permbuf[] = "---------";
11241136

1137+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
1138+
return;
11251139
fname = tv_get_string(&argvars[0]);
11261140

11271141
rettv->v_type = VAR_STRING;
@@ -1139,10 +1153,10 @@ f_getfsize(typval_T *argvars, typval_T *rettv)
11391153
char_u *fname;
11401154
stat_T st;
11411155

1142-
fname = tv_get_string(&argvars[0]);
1143-
1144-
rettv->v_type = VAR_NUMBER;
1156+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
1157+
return;
11451158

1159+
fname = tv_get_string(&argvars[0]);
11461160
if (mch_stat((char *)fname, &st) >= 0)
11471161
{
11481162
if (mch_isdir(fname))
@@ -1169,8 +1183,9 @@ f_getftime(typval_T *argvars, typval_T *rettv)
11691183
char_u *fname;
11701184
stat_T st;
11711185

1186+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
1187+
return;
11721188
fname = tv_get_string(&argvars[0]);
1173-
11741189
if (mch_stat((char *)fname, &st) >= 0)
11751190
rettv->vval.v_number = (varnumber_T)st.st_mtime;
11761191
else
@@ -1214,6 +1229,8 @@ f_getftype(typval_T *argvars, typval_T *rettv)
12141229
stat_T st;
12151230
char_u *type = NULL;
12161231

1232+
if (in_vim9script() && check_for_string(&argvars[0]) == FAIL)
1233+
return;
12171234
fname = tv_get_string(&argvars[0]);
12181235

12191236
rettv->v_type = VAR_STRING;

src/mbyte.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5551,13 +5551,8 @@ f_setcellwidths(typval_T *argvars, typval_T *rettv UNUSED)
55515551
void
55525552
f_charclass(typval_T *argvars, typval_T *rettv UNUSED)
55535553
{
5554-
if (argvars[0].v_type != VAR_STRING
5555-
|| argvars[0].vval.v_string == NULL
5556-
|| *argvars[0].vval.v_string == NUL)
5557-
{
5558-
emsg(_(e_stringreq));
5554+
if (check_for_string(&argvars[0]) == FAIL)
55595555
return;
5560-
}
55615556
rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string);
55625557
}
55635558
#endif

src/proto/typval.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ varnumber_T tv_get_number_chk(typval_T *varp, int *denote);
99
varnumber_T tv_get_bool(typval_T *varp);
1010
varnumber_T tv_get_bool_chk(typval_T *varp, int *denote);
1111
float_T tv_get_float(typval_T *varp);
12+
int check_for_string(typval_T *tv);
1213
char_u *tv_get_string(typval_T *varp);
1314
char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
1415
char_u *tv_get_string_chk(typval_T *varp);

src/testdir/test_vim9_builtin.vim

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ def Test_count()
185185
count('ABC ABC ABC', 'b', false)->assert_equal(0)
186186
enddef
187187

188+
def Test_executable()
189+
CheckDefExecFailure(['echo executable(true)'], 'E928:')
190+
CheckDefExecFailure(['echo executable(v:null)'], 'E928:')
191+
CheckDefExecFailure(['echo executable("")'], 'E928:')
192+
enddef
193+
194+
def Test_exepath()
195+
CheckDefExecFailure(['echo exepath(true)'], 'E928:')
196+
CheckDefExecFailure(['echo exepath(v:null)'], 'E928:')
197+
CheckDefExecFailure(['echo exepath("")'], 'E928:')
198+
enddef
199+
188200
def Test_expand()
189201
split SomeFile
190202
expand('%', true, true)->assert_equal(['SomeFile'])
@@ -241,6 +253,39 @@ def Test_map_function_arg()
241253
CheckDefAndScriptSuccess(lines)
242254
enddef
243255

256+
def Test_filereadable()
257+
CheckDefExecFailure(['echo filereadable(true)'], 'E928:')
258+
CheckDefExecFailure(['echo filereadable(v:null)'], 'E928:')
259+
CheckDefExecFailure(['echo filereadable("")'], 'E928:')
260+
enddef
261+
262+
def Test_filewritable()
263+
CheckDefExecFailure(['echo filewritable(true)'], 'E928:')
264+
CheckDefExecFailure(['echo filewritable(v:null)'], 'E928:')
265+
CheckDefExecFailure(['echo filewritable("")'], 'E928:')
266+
enddef
267+
268+
def Test_finddir()
269+
CheckDefExecFailure(['echo finddir(true)'], 'E928:')
270+
CheckDefExecFailure(['echo finddir(v:null)'], 'E928:')
271+
CheckDefExecFailure(['echo finddir("")'], 'E928:')
272+
enddef
273+
274+
def Test_findfile()
275+
CheckDefExecFailure(['echo findfile(true)'], 'E928:')
276+
CheckDefExecFailure(['echo findfile(v:null)'], 'E928:')
277+
CheckDefExecFailure(['echo findfile("")'], 'E928:')
278+
enddef
279+
280+
def Test_fnamemodify()
281+
CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E928:')
282+
CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E928:')
283+
CheckDefExecFailure(['echo fnamemodify("", ":p")'], 'E928:')
284+
CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E928:')
285+
CheckDefExecFailure(['echo fnamemodify("file", v:null)'], 'E928:')
286+
CheckDefExecFailure(['echo fnamemodify("file", "")'], 'E928:')
287+
enddef
288+
244289
def Test_filter_wrong_dict_key_type()
245290
assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
246291
enddef
@@ -313,6 +358,30 @@ def Test_getloclist_return_type()
313358
d->assert_equal({items: []})
314359
enddef
315360

361+
def Test_getfperm()
362+
CheckDefExecFailure(['echo getfperm(true)'], 'E928:')
363+
CheckDefExecFailure(['echo getfperm(v:null)'], 'E928:')
364+
CheckDefExecFailure(['echo getfperm("")'], 'E928:')
365+
enddef
366+
367+
def Test_getfsize()
368+
CheckDefExecFailure(['echo getfsize(true)'], 'E928:')
369+
CheckDefExecFailure(['echo getfsize(v:null)'], 'E928:')
370+
CheckDefExecFailure(['echo getfsize("")'], 'E928:')
371+
enddef
372+
373+
def Test_getftime()
374+
CheckDefExecFailure(['echo getftime(true)'], 'E928:')
375+
CheckDefExecFailure(['echo getftime(v:null)'], 'E928:')
376+
CheckDefExecFailure(['echo getftime("")'], 'E928:')
377+
enddef
378+
379+
def Test_getftype()
380+
CheckDefExecFailure(['echo getftype(true)'], 'E928:')
381+
CheckDefExecFailure(['echo getftype(v:null)'], 'E928:')
382+
CheckDefExecFailure(['echo getftype("")'], 'E928:')
383+
enddef
384+
316385
def Test_getqflist_return_type()
317386
var l = getqflist()
318387
l->assert_equal([])

src/testdir/test_vim9_expr.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,7 +1971,7 @@ def Test_expr7_dict()
19711971
CheckDefExecFailure(['var x: dict<string> = {a: "x", b: 134}'], 'E1012:', 1)
19721972

19731973
CheckDefFailure(['var x = ({'], 'E723:', 2)
1974-
CheckDefExecFailure(['{}[getftype("")]'], 'E716: Key not present in Dictionary: ""', 1)
1974+
CheckDefExecFailure(['{}[getftype("file")]'], 'E716: Key not present in Dictionary: ""', 1)
19751975
enddef
19761976

19771977
def Test_expr7_dict_vim9script()

src/typval.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,22 @@ tv_get_float(typval_T *varp)
340340
}
341341
#endif
342342

343+
/*
344+
* Give an error and return FAIL unless "tv" is a non-empty string.
345+
*/
346+
int
347+
check_for_string(typval_T *tv)
348+
{
349+
if (tv->v_type != VAR_STRING
350+
|| tv->vval.v_string == NULL
351+
|| *tv->vval.v_string == NUL)
352+
{
353+
emsg(_(e_stringreq));
354+
return FAIL;
355+
}
356+
return OK;
357+
}
358+
343359
/*
344360
* Get the string value of a variable.
345361
* If it is a Number variable, the number is converted into a string.

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2117,
753755
/**/
754756
2116,
755757
/**/

0 commit comments

Comments
 (0)