fix(buffer): defer w_buffer clearing to prevent dict watcher crash #36748

This commit is contained in:
CompileAndConquer
2025-11-30 20:56:53 -05:00
committed by GitHub
parent cdc6f85111
commit f9ef1a4cab
2 changed files with 58 additions and 1 deletions

View File

@@ -686,10 +686,14 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
return false;
}
bool clear_w_buf = false;
if (win != NULL // Avoid bogus clang warning.
&& win_valid_any_tab(win)
&& win->w_buffer == buf) {
win->w_buffer = NULL; // make sure we don't use the buffer now
// Defer clearing w_buffer until after operations that may invoke dict
// watchers (e.g., buf_clear_file()), so callers like tabpagebuflist()
// never see a window in the winlist with a NULL buffer.
clear_w_buf = true;
}
// Autocommands may have opened or closed windows for this buffer.
@@ -700,6 +704,9 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
// Remove the buffer from the list.
if (wipe_buf) {
if (clear_w_buf) {
win->w_buffer = NULL;
}
// Do not wipe out the buffer if it is used in a window.
if (buf->b_nwindows > 0) {
return true;
@@ -737,6 +744,9 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
buf->b_p_initialized = false;
}
buf_clear_file(buf);
if (clear_w_buf) {
win->w_buffer = NULL;
}
if (del_buf) {
buf->b_p_bl = false;
}