summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-04-06 21:12:42 +0200
committerBram Moolenaar <Bram@vim.org>2020-04-06 21:12:42 +0200
commit15352dc6ec43fd50cc3be4f4fd1ad74d5619da20 (patch)
treeead8831f915f42ef288759af0ae8a2bdda4bc5a9
parent6c307dcd554a1ce14c4279a3c2ede29f972bdb23 (diff)
patch 8.2.0521: crash when reading a blob failsv8.2.0521
Problem: Crash when reading a blob fails. Solution: Avoid keeping a pointer to a freed blob object. (Dominique Pelle, closes #5890) Adjust error messages.
-rw-r--r--src/filepath.c22
-rw-r--r--src/testdir/test_blob.vim3
-rw-r--r--src/version.c2
3 files changed, 16 insertions, 11 deletions
diff --git a/src/filepath.c b/src/filepath.c
index 37455a2569..15372af8e2 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -1452,20 +1452,18 @@ f_readfile(typval_T *argvars, typval_T *rettv)
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 *rettv)
{
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;
diff --git a/src/testdir/test_blob.vim b/src/testdir/test_blob.vim
index 2e5ef0b1c0..0170f547fa 100644
--- 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
diff --git a/src/version.c b/src/version.c
index b73dd6143a..22ac6a8316 100644
--- 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,