mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 13:15:09 -07:00
vim-patch:8.2.2476: using freed memory when splitting window while closing buffer
Problem: Using freed memory when using an autocommand to split a window
while a buffer is being closed.
Solution: Disallow splitting when the buffer has b_locked_split set.
983d83ff1c
Put the error message in window.c.
Cherry-pick a memory leak fix from Vim patch 8.2.0399.
Test still fails.
This commit is contained in:
parent
407be5975d
commit
1664e3d4bc
@ -466,6 +466,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
||||
// When the buffer is no longer in a window, trigger BufWinLeave
|
||||
if (buf->b_nwindows == 1) {
|
||||
buf->b_locked++;
|
||||
buf->b_locked_split++;
|
||||
if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false,
|
||||
buf) && !bufref_valid(&bufref)) {
|
||||
// Autocommands deleted the buffer.
|
||||
@ -473,6 +474,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
||||
return false;
|
||||
}
|
||||
buf->b_locked--;
|
||||
buf->b_locked_split--;
|
||||
if (abort_if_last && last_nonfloat(win)) {
|
||||
// Autocommands made this the only window.
|
||||
emsg(_(e_auabort));
|
||||
@ -483,6 +485,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
||||
// BufHidden
|
||||
if (!unload_buf) {
|
||||
buf->b_locked++;
|
||||
buf->b_locked_split++;
|
||||
if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false,
|
||||
buf) && !bufref_valid(&bufref)) {
|
||||
// Autocommands deleted the buffer.
|
||||
@ -490,6 +493,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
||||
return false;
|
||||
}
|
||||
buf->b_locked--;
|
||||
buf->b_locked_split--;
|
||||
if (abort_if_last && last_nonfloat(win)) {
|
||||
// Autocommands made this the only window.
|
||||
emsg(_(e_auabort));
|
||||
@ -678,6 +682,7 @@ void buf_freeall(buf_T *buf, int flags)
|
||||
|
||||
// Make sure the buffer isn't closed by autocommands.
|
||||
buf->b_locked++;
|
||||
buf->b_locked_split++;
|
||||
|
||||
bufref_T bufref;
|
||||
set_bufref(&bufref, buf);
|
||||
@ -703,6 +708,7 @@ void buf_freeall(buf_T *buf, int flags)
|
||||
return;
|
||||
}
|
||||
buf->b_locked--;
|
||||
buf->b_locked_split--;
|
||||
|
||||
// If the buffer was in curwin and the window has changed, go back to that
|
||||
// window, if it still exists. This avoids that ":edit x" triggering a
|
||||
@ -1466,8 +1472,8 @@ void set_curbuf(buf_T *buf, int action)
|
||||
set_bufref(&prevbufref, prevbuf);
|
||||
set_bufref(&newbufref, buf);
|
||||
|
||||
// Autocommands may delete the current buffer and/or the buffer we want to go
|
||||
// to. In those cases don't close the buffer.
|
||||
// Autocommands may delete the current buffer and/or the buffer we want to
|
||||
// go to. In those cases don't close the buffer.
|
||||
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
|
||||
|| (bufref_valid(&prevbufref) && bufref_valid(&newbufref)
|
||||
&& !aborting())) {
|
||||
|
@ -532,6 +532,8 @@ struct file_buffer {
|
||||
int b_flags; // various BF_ flags
|
||||
int b_locked; // Buffer is being closed or referenced, don't
|
||||
// let autocommands wipe it out.
|
||||
int b_locked_split; // Buffer is being closed, don't allow opening
|
||||
// a new window with it.
|
||||
int b_ro_locked; // Non-zero when the buffer can't be changed.
|
||||
// Used for FileChangedRO
|
||||
|
||||
|
@ -6376,6 +6376,7 @@ static int open_cmdwin(void)
|
||||
// Create a window for the command-line buffer.
|
||||
if (win_split((int)p_cwh, WSP_BOT) == FAIL) {
|
||||
beep_flush();
|
||||
ga_clear(&winsizes);
|
||||
return K_IGNORE;
|
||||
}
|
||||
cmdwin_type = get_cmdline_type();
|
||||
|
@ -2717,17 +2717,14 @@ endfunc
|
||||
|
||||
" Fuzzer found some strange combination that caused a crash.
|
||||
func Test_autocmd_normal_mess()
|
||||
" TODO: why does this hang on Windows?
|
||||
CheckNotMSWindows
|
||||
|
||||
augroup aucmd_normal_test
|
||||
au BufLeave,BufWinLeave,BufHidden,BufUnload,BufDelete,BufWipeout * norm 7q/qc
|
||||
augroup END
|
||||
" Nvim has removed :open
|
||||
" o4
|
||||
e4
|
||||
" call assert_fails('o4', 'E1159')
|
||||
call assert_fails('e4', 'E1159')
|
||||
silent! H
|
||||
e xx
|
||||
call assert_fails('e xx', 'E1159')
|
||||
normal G
|
||||
|
||||
augroup aucmd_normal_test
|
||||
@ -2749,7 +2746,7 @@ func Test_autocmd_vimgrep()
|
||||
au QuickfixCmdPre,BufNew,BufDelete,BufReadCmd * sb
|
||||
au QuickfixCmdPre,BufNew,BufDelete,BufReadCmd * q9 |