aboutsummaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorMarco Hinz <mh.codebro@gmail.com>2014-04-14 16:47:00 +0200
committerThiago de Arruda <tpadilha84@gmail.com>2014-04-16 09:46:01 -0300
commitcb0adf60de98003564105169dee4bc792c56a559 (patch)
tree92549d91a2d431fafffb2ac841459ac22d94d8c0 /src/buffer.c
parent40970917dcd35c8e986c3dc678bf180a2b2ddf24 (diff)
downloadrneovim-cb0adf60de98003564105169dee4bc792c56a559.tar.gz
rneovim-cb0adf60de98003564105169dee4bc792c56a559.tar.bz2
rneovim-cb0adf60de98003564105169dee4bc792c56a559.zip
vim-patch:7.4.251
Problem: Crash when BufAdd autocommand wipes out the buffer. Solution: Check for buffer to still be valid. Postpone freeing the buffer structure. (Hirohito Higashi) https://code.google.com/p/vim/source/detail?r=29eb4c2a33ac701bfcd4d2e2bed7864eba876e0e
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/buffer.c b/src/buffer.c
index d25ed10ac7..7402c57ec8 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -550,7 +550,14 @@ static void free_buffer(buf_T *buf)
free_buffer_stuff(buf, TRUE);
unref_var_dict(buf->b_vars);
aubuflocal_remove(buf);
- vim_free(buf);
+ if (autocmd_busy) {
+ // Do not free the buffer structure while autocommands are executing,
+ // it's still needed. Free it when autocmd_busy is reset.
+ buf->b_next = au_pending_free_buf;
+ au_pending_free_buf = buf;
+ } else {
+ vim_free(buf);
+ }
}
/*
@@ -1332,8 +1339,12 @@ buflist_new (
buf_copy_options(buf, 0);
if ((flags & BLN_LISTED) && !buf->b_p_bl) {
buf->b_p_bl = TRUE;
- if (!(flags & BLN_DUMMY))
+ if (!(flags & BLN_DUMMY)) {
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+ if (!buf_valid(buf)) {
+ return NULL;
+ }
+ }
}
return buf;
}
@@ -1469,8 +1480,15 @@ buflist_new (
buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE; /* init 'buflisted' */
if (!(flags & BLN_DUMMY)) {
apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
- if (flags & BLN_LISTED)
+ if (!buf_valid(buf)) {
+ return NULL;
+ }
+ if (flags & BLN_LISTED) {
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+ if (!buf_valid(buf)) {
+ return NULL;
+ }
+ }
if (aborting()) /* autocmds may abort script processing */
return NULL;
}