mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(nvim_open_win): crash if autocmds delete buffer/window #15549
win_set_buf can trigger autocmds if noautocmd=false. If they close the window,
code afterwards will dereference the freed win_T* wp pointer.
This interaction became possible after commit 1def3d1542.
The reason deleting curbuf crashes, and not the buf passed to
`nvim_open_win`, is because the float initially edits curbuf (`win_init`)
until it's later set to edit buf (windows from `:new` and `:split <buf>`
behave similiarly: approx. `:split`, then `:buffer <buf>`).
`do_buffer` closes windows when their edited buffer is deleted (unless
it's the only window; N/A for floats), so the float closes when curbuf
is deleted, so we need to check `win_valid` after `win_set_buf` too.
Closes #15548
			
			
This commit is contained in:
		| @@ -1439,13 +1439,14 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err | ||||
|   if (enter) { | ||||
|     win_enter(wp, false); | ||||
|   } | ||||
|   // autocmds in win_enter or win_set_buf below may close the window | ||||
|   if (win_valid(wp) && buffer > 0) { | ||||
|     win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); | ||||
|   } | ||||
|   if (!win_valid(wp)) { | ||||
|     api_set_error(err, kErrorTypeException, "Window was closed immediately"); | ||||
|     return 0; | ||||
|   } | ||||
|   if (buffer > 0) { | ||||
|     win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); | ||||
|   } | ||||
|  | ||||
|   if (fconfig.style == kWinStyleMinimal) { | ||||
|     win_set_minimal_style(wp); | ||||
|   | ||||
| @@ -109,6 +109,21 @@ describe('float window', function() | ||||
|     assert_alive() | ||||
|   end) | ||||
|  | ||||
|   it('closed immediately by autocmd after win_enter #15548', function() | ||||
|     eq('Error executing lua: [string "<nvim>"]:0: Window was closed immediately', | ||||
|       pcall_err(exec_lua, [[ | ||||
|         vim.cmd "autocmd BufLeave * ++once quit!" | ||||
|         local buf = vim.api.nvim_create_buf(true, true) | ||||
|         vim.api.nvim_open_win(buf, true, { | ||||
|           relative = "win", | ||||
|           row = 0, col = 0, | ||||
|           width = 1, height = 1, | ||||
|           noautocmd = false, | ||||
|         }) | ||||
|     ]])) | ||||
|     assert_alive() | ||||
|   end) | ||||
|  | ||||
|   it('opened with correct height', function() | ||||
|     local height = exec_lua([[ | ||||
|       vim.api.nvim_set_option("winheight", 20) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sean Dewar
					Sean Dewar