diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-06-13 19:38:37 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-06-13 19:38:37 +0200 |
commit | 8cf91286ca46a501d24e4b7d631b193256782c88 (patch) | |
tree | 98d8c9d8c4b6a9c88376b64b56fbadf74bff3f13 | |
parent | 3ec574f2b549f456f664f689d6da36dc5719aeb9 (diff) | |
download | vim-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.c | 24 | ||||
-rw-r--r-- | src/testdir/test_writefile.vim | 21 | ||||
-rw-r--r-- | src/version.c | 2 |
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, |