Skip to content

Commit 8cf9128

Browse files
committed
patch 8.0.0642: writefile() continues after detecting an error
Problem: writefile() continues after detecting an error. Solution: Bail out as soon as an error is detected. (suggestions by Nikolai Pavlov, closes #1476)
1 parent 3ec574f commit 8cf9128

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

src/evalfunc.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13179,7 +13179,10 @@ f_writefile(typval_T *argvars, typval_T *rettv)
1317913179
char_u *fname;
1318013180
FILE *fd;
1318113181
int ret = 0;
13182+
listitem_T *li;
13183+
list_T *list;
1318213184

13185+
rettv->vval.v_number = -1;
1318313186
if (check_restricted() || check_secure())
1318413187
return;
1318513188

@@ -13188,20 +13191,31 @@ f_writefile(typval_T *argvars, typval_T *rettv)
1318813191
EMSG2(_(e_listarg), "writefile()");
1318913192
return;
1319013193
}
13191-
if (argvars[0].vval.v_list == NULL)
13194+
list = argvars[0].vval.v_list;
13195+
if (list == NULL)
1319213196
return;
13197+
for (li = list->lv_first; li != NULL; li = li->li_next)
13198+
if (get_tv_string_chk(&li->li_tv) == NULL)
13199+
return;
1319313200

1319413201
if (argvars[2].v_type != VAR_UNKNOWN)
1319513202
{
13196-
if (vim_strchr(get_tv_string(&argvars[2]), 'b') != NULL)
13203+
char_u *arg2 = get_tv_string_chk(&argvars[2]);
13204+
13205+
if (arg2 == NULL)
13206+
return;
13207+
if (vim_strchr(arg2, 'b') != NULL)
1319713208
binary = TRUE;
13198-
if (vim_strchr(get_tv_string(&argvars[2]), 'a') != NULL)
13209+
if (vim_strchr(arg2, 'a') != NULL)
1319913210
append = TRUE;
1320013211
}
1320113212

13213+
fname = get_tv_string_chk(&argvars[1]);
13214+
if (fname == NULL)
13215+
return;
13216+
1320213217
/* Always open the file in binary mode, library functions have a mind of
1320313218
* their own about CR-LF conversion. */
13204-
fname = get_tv_string(&argvars[1]);
1320513219
if (*fname == NUL || (fd = mch_fopen((char *)fname,
1320613220
append ? APPENDBIN : WRITEBIN)) == NULL)
1320713221
{
@@ -13210,7 +13224,7 @@ f_writefile(typval_T *argvars, typval_T *rettv)
1321013224
}
1321113225
else
1321213226
{
13213-
if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL)
13227+
if (write_list(fd, list, binary) == FAIL)
1321413228
ret = -1;
1321513229
fclose(fd);
1321613230
}

src/testdir/test_writefile.vim

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
" Tests for the writefile() function.
12

2-
function! Test_WriteFile()
3+
func Test_writefile()
34
let f = tempname()
45
call writefile(["over","written"], f, "b")
56
call writefile(["hello","world"], f, "b")
@@ -13,4 +14,20 @@ function! Test_WriteFile()
1314
call assert_equal("morning", l[3])
1415
call assert_equal("vimmers", l[4])
1516
call delete(f)
16-
endfunction
17+
endfunc
18+
19+
func Test_writefile_fails_gently()
20+
call assert_fails('call writefile(["test"], "Xfile", [])', 'E730:')
21+
call assert_false(filereadable("Xfile"))
22+
call delete("Xfile")
23+
24+
call assert_fails('call writefile(["test", [], [], [], "tset"], "Xfile")', 'E730:')
25+
call assert_false(filereadable("Xfile"))
26+
call delete("Xfile")
27+
28+
call assert_fails('call writefile([], "Xfile", [])', 'E730:')
29+
call assert_false(filereadable("Xfile"))
30+
call delete("Xfile")
31+
32+
call assert_fails('call writefile([], [])', 'E730:')
33+
endfunc

src/version.c

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

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
642,
767769
/**/
768770
641,
769771
/**/

0 commit comments

Comments
 (0)