diff --git a/src/nvim/window.c b/src/nvim/window.c index d8800c15f9..68f202ce34 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2092,10 +2092,10 @@ void win_move_after(win_T *win1, win_T *win2) win_comp_pos(); // recompute w_winrow for all windows redraw_later(curwin, UPD_NOT_VALID); } - win_enter(win1, false); - win1->w_pos_changed = true; win2->w_pos_changed = true; + + win_enter(win1, false); } /// Compute maximum number of windows that can fit within "height" in frame "fr". diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua index 6618140e23..d48cf0a27c 100644 --- a/test/functional/autocmd/autocmd_spec.lua +++ b/test/functional/autocmd/autocmd_spec.lua @@ -715,4 +715,20 @@ describe('autocmd', function() vim.cmd "tabnew" ]] end) + + it('no use-after-free from win_enter autocommands in win_move_after', function() + exec [[ + split foo + split bar + lcd .. + wincmd b + ]] + eq(fn.winnr('$'), fn.winnr()) + -- Using DirChanged as Enter/Leave autocmds are blocked by :ball here. + exec [[ + autocmd DirChanged * ++once split flarb | only! + ball + ]] + eq('flarb', fn.bufname()) + end) end)