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
This commit is contained in:
Marco Hinz 2014-04-14 16:47:00 +02:00 committed by Thiago de Arruda
parent 40970917dc
commit cb0adf60de
5 changed files with 39 additions and 8 deletions

View File

@ -550,7 +550,14 @@ static void free_buffer(buf_T *buf)
free_buffer_stuff(buf, TRUE); free_buffer_stuff(buf, TRUE);
unref_var_dict(buf->b_vars); unref_var_dict(buf->b_vars);
aubuflocal_remove(buf); 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); buf_copy_options(buf, 0);
if ((flags & BLN_LISTED) && !buf->b_p_bl) { if ((flags & BLN_LISTED) && !buf->b_p_bl) {
buf->b_p_bl = TRUE; buf->b_p_bl = TRUE;
if (!(flags & BLN_DUMMY)) if (!(flags & BLN_DUMMY)) {
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf); apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
if (!buf_valid(buf)) {
return NULL;
}
}
} }
return buf; return buf;
} }
@ -1469,8 +1480,15 @@ buflist_new (
buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE; /* init 'buflisted' */ buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE; /* init 'buflisted' */
if (!(flags & BLN_DUMMY)) { if (!(flags & BLN_DUMMY)) {
apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf); 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); apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
if (!buf_valid(buf)) {
return NULL;
}
}
if (aborting()) /* autocmds may abort script processing */ if (aborting()) /* autocmds may abort script processing */
return NULL; return NULL;
} }

View File

@ -2774,6 +2774,11 @@ do_ecmd (
} }
buf = buflist_new(ffname, sfname, 0L, buf = buflist_new(ffname, sfname, 0L,
BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED)); BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
// Autocmds may change curwin and curbuf.
if (oldwin != NULL) {
oldwin = curwin;
}
old_curbuf = curbuf;
} }
if (buf == NULL) if (buf == NULL)
goto theend; goto theend;

View File

@ -7525,14 +7525,17 @@ apply_autocmds_group (
vim_free(sfname); vim_free(sfname);
--nesting; /* see matching increment above */ --nesting; /* see matching increment above */
/* // When stopping to execute autocommands, restore the search patterns and
* When stopping to execute autocommands, restore the search patterns and // the redo buffer. Free buffers in the au_pending_free_buf list.
* the redo buffer.
*/
if (!autocmd_busy) { if (!autocmd_busy) {
restore_search_patterns(); restore_search_patterns();
restoreRedobuff(); restoreRedobuff();
did_filetype = FALSE; did_filetype = FALSE;
while (au_pending_free_buf != NULL) {
buf_T *b = au_pending_free_buf->b_next;
vim_free(au_pending_free_buf);
au_pending_free_buf = b;
}
} }
/* /*

View File

@ -352,6 +352,11 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
* which one is preferred, au_new_curbuf is set to it */ * which one is preferred, au_new_curbuf is set to it */
EXTERN buf_T *au_new_curbuf INIT(= NULL); EXTERN buf_T *au_new_curbuf INIT(= NULL);
// When deleting the buffer and autocmd_busy is TRUE, do not free the buffer
// but link it in the list starting with au_pending_free_buf, using b_next.
// Free the buffer when autocmd_busy is set to FALSE.
EXTERN buf_T *au_pending_free_buf INIT(= NULL);
/* /*
* Mouse coordinates, set by check_termcode() * Mouse coordinates, set by check_termcode()
*/ */

View File

@ -209,7 +209,7 @@ static int included_patches[] = {
//254, //254,
//253, //253,
//252, //252,
//251, 251,
//250, //250,
//249, //249,
//248, //248,