]> granicus.if.org Git - vim/commitdiff
patch 8.0.0642: writefile() continues after detecting an error v8.0.0642
authorBram Moolenaar <Bram@vim.org>
Tue, 13 Jun 2017 17:38:37 +0000 (19:38 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 13 Jun 2017 17:38:37 +0000 (19:38 +0200)
Problem:    writefile() continues after detecting an error.
Solution:   Bail out as soon as an error is detected. (suggestions by Nikolai
            Pavlov, closes #1476)

src/evalfunc.c
src/testdir/test_writefile.vim
src/version.c

index c198df13a920f5d4320acf1937bf2b359c3fe9a6..8167abd60f9b855108ca813b61f2bd6fac6a6ed7 100644 (file)
@@ -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);
     }
index d820c580acff512d94c75e64d27823e944b7064b..13c1a888d921089eb53115394cb17f2232c96778 100644 (file)
@@ -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
index 365dbc5c0dcaf0de8aa98969469b41a2977bef89..6f5c8938e3fa4f377f763516c769232785f9d9c4 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    642,
 /**/
     641,
 /**/