diff options
author | Marco Hinz <mh.codebro@gmail.com> | 2014-04-14 16:47:00 +0200 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-04-16 09:46:01 -0300 |
commit | cb0adf60de98003564105169dee4bc792c56a559 (patch) | |
tree | 92549d91a2d431fafffb2ac841459ac22d94d8c0 /src/buffer.c | |
parent | 40970917dcd35c8e986c3dc678bf180a2b2ddf24 (diff) | |
download | rneovim-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.c | 24 |
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; } |