changeset 19930:80e663e91e1b v8.2.0521

patch 8.2.0521: crash when reading a blob fails Commit: https://github.com/vim/vim/commit/15352dc6ec43fd50cc3be4f4fd1ad74d5619da20 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Apr 6 21:12:42 2020 +0200 patch 8.2.0521: crash when reading a blob fails Problem: Crash when reading a blob fails. Solution: Avoid keeping a pointer to a freed blob object. (Dominique Pelle, closes #5890) Adjust error messages.
author Bram Moolenaar <Bram@vim.org>
date Mon, 06 Apr 2020 21:15:37 +0200
parents 35310c0dd026
children db6b095f4073
files src/filepath.c src/testdir/test_blob.vim src/version.c
diffstat 3 files changed, 16 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -1452,20 +1452,18 @@ f_readfile(typval_T *argvars, typval_T *
 	    maxline = (long)tv_get_number(&argvars[2]);
     }
 
-    if (blob)
-    {
-	if (rettv_blob_alloc(rettv) == FAIL)
-	    return;
-    }
-    else
-    {
-	if (rettv_list_alloc(rettv) == FAIL)
-	    return;
-    }
+    if ((blob ? rettv_blob_alloc(rettv) : rettv_list_alloc(rettv)) == FAIL)
+	return;
 
     // Always open the file in binary mode, library functions have a mind of
     // their own about CR-LF conversion.
     fname = tv_get_string(&argvars[0]);
+
+    if (mch_isdir(fname))
+    {
+	semsg(_(e_isadir2), fname);
+	return;
+    }
     if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL)
     {
 	semsg(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname);
@@ -1476,8 +1474,10 @@ f_readfile(typval_T *argvars, typval_T *
     {
 	if (read_blob(fd, rettv->vval.v_blob) == FAIL)
 	{
-	    emsg("cannot read file");
+	    semsg(_(e_notread), fname);
+	    // An empty blob is returned on error.
 	    blob_free(rettv->vval.v_blob);
+	    rettv->vval.v_blob = NULL;
 	}
 	fclose(fd);
 	return;
--- a/src/testdir/test_blob.vim
+++ b/src/testdir/test_blob.vim
@@ -257,6 +257,9 @@ func Test_blob_read_write()
   let br = readfile('Xblob', 'B')
   call assert_equal(b, br)
   call delete('Xblob')
+
+  " This was crashing when calling readfile() with a directory.
+  call assert_fails("call readfile('.', 'B')", 'E17: "." is a directory')
 endfunc
 
 " filter() item in blob
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    521,
+/**/
     520,
 /**/
     519,