summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-06-13 19:38:37 +0200
committerBram Moolenaar <Bram@vim.org>2017-06-13 19:38:37 +0200
commit8cf91286ca46a501d24e4b7d631b193256782c88 (patch)
tree98d8c9d8c4b6a9c88376b64b56fbadf74bff3f13
parent3ec574f2b549f456f664f689d6da36dc5719aeb9 (diff)
downloadvim-git-8cf91286ca46a501d24e4b7d631b193256782c88.tar.gz
patch 8.0.0642: writefile() continues after detecting an errorv8.0.0642
Problem: writefile() continues after detecting an error. Solution: Bail out as soon as an error is detected. (suggestions by Nikolai Pavlov, closes #1476)
-rw-r--r--src/evalfunc.c24
-rw-r--r--src/testdir/test_writefile.vim21
-rw-r--r--src/version.c2
3 files changed, 40 insertions, 7 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index c198df13a..8167abd60 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -13179,7 +13179,10 @@ f_writefile(typval_T *argvars, typval_T *rettv)
char_u *fname;
FILE *fd;
int ret = 0;
+ listitem_T *li;
+ list_T *list;
+ rettv->vval.v_number = -1;
if (check_restricted() || check_secure())
return;
@@ -13188,20 +13191,31 @@ f_writefile(typval_T *argvars, typval_T *rettv)
EMSG2(_(e_listarg), "writefile()");
return;
}
- if (argvars[0].vval.v_list == NULL)
+ list = argvars[0].vval.v_list;
+ if (list == NULL)
return;
+ for (li = list->lv_first; li != NULL; li = li->li_next)
+ if (get_tv_string_chk(&li->li_tv) == NULL)
+ return;
if (argvars[2].v_type != VAR_UNKNOWN)
{
- if (vim_strchr(get_tv_string(&argvars[2]), 'b') != NULL)
+ char_u *arg2 = get_tv_string_chk(&argvars[2]);
+
+ if (arg2 == NULL)
+ return;
+ if (vim_strchr(arg2, 'b') != NULL)
binary = TRUE;
- if (vim_strchr(get_tv_string(&argvars[2]), 'a') != NULL)
+ if (vim_strchr(arg2, 'a') != NULL)
append = TRUE;
}
+ fname = get_tv_string_chk(&argvars[1]);
+ if (fname == NULL)
+ return;
+
/* Always open the file in binary mode, library functions have a mind of
* their own about CR-LF conversion. */
- fname = get_tv_string(&argvars[1]);
if (*fname == NUL || (fd = mch_fopen((char *)fname,
append ? APPENDBIN : WRITEBIN)) == NULL)
{
@@ -13210,7 +13224,7 @@ f_writefile(typval_T *argvars, typval_T *rettv)
}
else
{
- if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL)
+ if (write_list(fd, list, binary) == FAIL)
ret = -1;
fclose(fd);
}
diff --git a/src/testdir/test_writefile.vim b/src/testdir/test_writefile.vim
index d820c580a..13c1a888d 100644
--- a/src/testdir/test_writefile.vim
+++ b/src/testdir/test_writefile.vim
@@ -1,5 +1,6 @@
+" Tests for the writefile() function.
-function! Test_WriteFile()
+func Test_writefile()
let f = tempname()
call writefile(["over","written"], f, "b")
call writefile(["hello","world"], f, "b")
@@ -13,4 +14,20 @@ function! Test_WriteFile()
call assert_equal("morning", l[3])
call assert_equal("vimmers", l[4])
call delete(f)
-endfunction
+endfunc
+
+func Test_writefile_fails_gently()
+ call assert_fails('call writefile(["test"], "Xfile", [])', 'E730:')
+ call assert_false(filereadable("Xfile"))
+ call delete("Xfile")
+
+ call assert_fails('call writefile(["test", [], [], [], "tset"], "Xfile")', 'E730:')
+ call assert_false(filereadable("Xfile"))
+ call delete("Xfile")
+
+ call assert_fails('call writefile([], "Xfile", [])', 'E730:')
+ call assert_false(filereadable("Xfile"))
+ call delete("Xfile")
+
+ call assert_fails('call writefile([], [])', 'E730:')
+endfunc
diff --git a/src/version.c b/src/version.c
index 365dbc5c0..6f5c8938e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 642,
+/**/
641,
/**/
640,