Skip to content

Commit fc5be94

Browse files
committed
updated for version 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)
1 parent 421a5e7 commit fc5be94

5 files changed

Lines changed: 39 additions & 2 deletions

File tree

src/buffer.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,8 +676,16 @@ free_buffer(buf)
676676
#endif
677677
#ifdef FEAT_AUTOCMD
678678
aubuflocal_remove(buf);
679+
if (autocmd_busy)
680+
{
681+
/* Do not free the buffer structure while autocommands are executing,
682+
* it's still needed. Free it when autocmd_busy is reset. */
683+
buf->b_next = au_pending_free_buf;
684+
au_pending_free_buf = buf;
685+
}
686+
else
679687
#endif
680-
vim_free(buf);
688+
vim_free(buf);
681689
}
682690

683691
/*
@@ -1681,7 +1689,11 @@ buflist_new(ffname, sfname, lnum, flags)
16811689
buf->b_p_bl = TRUE;
16821690
#ifdef FEAT_AUTOCMD
16831691
if (!(flags & BLN_DUMMY))
1692+
{
16841693
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
1694+
if (!buf_valid(buf))
1695+
return NULL;
1696+
}
16851697
#endif
16861698
}
16871699
return buf;
@@ -1857,8 +1869,14 @@ buflist_new(ffname, sfname, lnum, flags)
18571869
if (!(flags & BLN_DUMMY))
18581870
{
18591871
apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
1872+
if (!buf_valid(buf))
1873+
return NULL;
18601874
if (flags & BLN_LISTED)
1875+
{
18611876
apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
1877+
if (!buf_valid(buf))
1878+
return NULL;
1879+
}
18621880
# ifdef FEAT_EVAL
18631881
if (aborting()) /* autocmds may abort script processing */
18641882
return NULL;

src/ex_cmds.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3343,6 +3343,12 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
33433343
#endif
33443344
buf = buflist_new(ffname, sfname, 0L,
33453345
BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
3346+
#ifdef FEAT_AUTOCMD
3347+
/* autocommands may change curwin and curbuf */
3348+
if (oldwin != NULL)
3349+
oldwin = curwin;
3350+
old_curbuf = curbuf;
3351+
#endif
33463352
}
33473353
if (buf == NULL)
33483354
goto theend;

src/fileio.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9548,13 +9548,19 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
95489548

95499549
/*
95509550
* When stopping to execute autocommands, restore the search patterns and
9551-
* the redo buffer.
9551+
* the redo buffer. Free buffers in the au_pending_free_buf list.
95529552
*/
95539553
if (!autocmd_busy)
95549554
{
95559555
restore_search_patterns();
95569556
restoreRedobuff();
95579557
did_filetype = FALSE;
9558+
while (au_pending_free_buf != NULL)
9559+
{
9560+
buf_T *b = au_pending_free_buf->b_next;
9561+
vim_free(au_pending_free_buf);
9562+
au_pending_free_buf = b;
9563+
}
95589564
}
95599565

95609566
/*

src/globals.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,11 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
386386
/* When deleting the current buffer, another one must be loaded. If we know
387387
* which one is preferred, au_new_curbuf is set to it */
388388
EXTERN buf_T *au_new_curbuf INIT(= NULL);
389+
390+
/* When deleting the buffer and autocmd_busy is TRUE, do not free the buffer
391+
* but link it in the list starting with au_pending_free_buf, using b_next.
392+
* Free the buffer when autocmd_busy is set to FALSE. */
393+
EXTERN buf_T *au_pending_free_buf INIT(= NULL);
389394
#endif
390395

391396
#ifdef FEAT_MOUSE

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ static char *(features[]) =
734734

735735
static int included_patches[] =
736736
{ /* Add new patch number below this line */
737+
/**/
738+
251,
737739
/**/
738740
250,
739741
/**/

0 commit comments

Comments
 (0)