mirror of
https://github.com/neovim/neovim.git
synced 2025-12-11 09:02:40 +00: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:
@@ -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())) {
|
||||
|
||||
Reference in New Issue
Block a user