diff --git a/src/nvim/window.c b/src/nvim/window.c index 0c0c00335a..7ff4a06e6d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2071,10 +2071,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 1b7275ebf6..9b5c1b5250 100644 --- a/test/functional/autocmd/autocmd_spec.lua +++ b/test/functional/autocmd/autocmd_spec.lua @@ -8,6 +8,7 @@ local dedent = t.dedent local eq = t.eq local neq = t.neq local eval = n.eval +local exec = n.exec local feed = n.feed local clear = n.clear local matches = t.matches @@ -695,4 +696,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)