Problem: Cmdline history not updated when mapping both <Up> and <CR>.
Solution: Consider the command typed when in Cmdline mode and there is
no pending input (zeertzjq).
Although the existing behavior technically does match documentation, the
"completely come from mappings" part is a bit ambiguous, because one may
argue that the command doesn't completely come from mappings as long as
the user has typed a key in Cmdline mode. I'm not entirely sure if this
change will cause problems, but it seems unlikely.
fixes: vim/vim#2771
related: neovim/neovim#36256closes: vim/vim#1860797b6e8b424
(cherry picked from commit 2407833ba1)
Problem: :wqall! doesn't quit when using :quit in BufWritePost
(after 8.0.1190).
Solution: Restore old value of "exiting" when calling not_exiting()
instead of always resetting it to FALSE (zeertzjq).
related: vim/vim#2205
closes: vim/vim#19212e803ad1c56
Problem:
Creating an autocommand which executes `:bwipe` on the Syntax event
causes a heap-use-after-free.
Solution: set BF_SYN_SET flag before applying autocommands
(cherry picked from commit f36dd7557a)
When width1 and width2 are negative the assertion may fail. It seems
that adding a negative value to w_curswant won't cause any problems, so
just change the assertion.
(cherry picked from commit 41068c77aa)
Problem: nvim_parse_expression null pointer dereference with unmatched ]
followed by a node.
Solution: if ast_stack was empty, set new_top_node_p to top of the stack after
pushing the list literal node; similar to what's done for curlies.
This bug was originally found by a Matrix user, but I couldn't remember how to
trigger it... Ran into the other crash while finding a repro. :P
(cherry picked from commit a5e5ec8910)
Problem: nvim_parse_expression null pointer dereference when parsing an
identifier followed by { with "highlight" parameter set to false.
Solution: only set opening_hl_idx if pstate->colors is not NULL.
Not added to parser_tests.lua as that uses highlight = true.
(cherry picked from commit 5226801be2)
Problem: Last buffer not freed with EXITFREE (after 9.1.2087).
Solution: Free the last buffer when inside free_all_mem()
(zeertzjq).
This isn't really a memory leak, as the last buffer's memory is still
reachable via pointers like firstbuf and lastbuf. But it's possible that
this may cause false ASAN warnings in the future, which is what EXITFREE
is supposed to prevent.
closes: vim/vim#191946c118afeaa
(cherry picked from commit 960cba7b3b)
Problem: Crash when using :tabonly in BufUnload.
Solution: Set curbuf when setting curwin->w_buffer. Don't wipe out a
buffer if there are no other buffers. Don't decrement
b_nwindows if it was 0 before buf_freeall() (zeertzjq).
fixes: vim/vim#19088#issuecomment-3710172769
closes: vim/vim#19186fa64f92f6a
(cherry picked from commit eb5a7cc0dd)
Problem: memory leak when not evaluating (just parsing) invalid literal
dict.
Solution: Always clear the key's typval (Sean Dewar)
Though "check_typval_is_value(&tv) == FAIL && !evaluate" is maybe never
true, also always clear tvs if check_typval_is_value fails; at worst
this would be a no-op as their initial types are VAR_UNKNOWN.
closes: vim/vim#19178b10a3e1a20
check_typval_is_value change is for Vim9 script. (from 9.0.2163)
N/A patch:
vim-patch:9.0.2163: Vim9: type can be assigned to list/dict
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
(cherry picked from commit ba1d50fdc3)
Problem: nvim_get_option_value with "filetype" set can crash if autocommands
open the dummy buffer in more windows, or if &bufhidden == "wipe".
Solution: Attempt to close all dummy buffer windows before wiping. Promote the
dummy buffer to a normal buffer if that fails.
(cherry picked from commit 7e2e116343)
Removed code doesn't seem to do anything? Looks like a clobbered remnant from
when do_filetype_autocmd lived in did_set_string_option.
Doc comment for wipe_buffer doesn't decrement top_file_num since a2d25b7 (2016),
which presumably means the comment on marks doesn't apply either. (fmark_T::fnum
can't refer to the wrong buffer as numbers aren't reused here anymore)
(cherry picked from commit 40114d1631)
Problem: When the "filetype" key is set for nvim_get_option_value, autocommands
can crash Nvim by prematurely wiping the dummy buffer, or cause options intended
for it to instead be set for unrelated buffers if switched during OptionSet.
Solution: Don't crash. Also quash side-effects from setting the buffer options.
(cherry picked from commit 3cb462a960)
This fixes a regression from cf6f60ce4d
(possibly), as before that commit a frame is popped from the call stack
immediately after its response is received.
Also fix leaking the allocated error messages.
(cherry picked from commit 39d8aa0a1a)
Problem: printf format not checked for semsg().
Solution: Add GNUC attribute and fix reported problems. (Dominique Pelle,
closesvim/vim#3805)
b5443cc46d
Cherry-pick a change from patch 8.2.3830.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
(cherry picked from commit ef522420f2)
Problem: :bdelete/bunload/bwipeout may attempt to switch to a closing
buffer, which fails. (after 9.1.2058)
Solution: don't consider switching to closing buffers (Sean Dewar)
closes: vim/vim#1910763d53de72d
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
(cherry picked from commit e002e4d7fc)
Problem: b_locked_split is not checked for :sbuffer, which allows
autocommands to leave windows open to freed buffers.
Solution: In do_buffer_ext, check just before possibly splitting, after
handling 'switchbuf'. Leave win_split to handle the check for
curbuf. (needed even if curbuf is not the target, as setting
the buffer after splitting may fail) (Sean Dewar)
closes: vim/vim#19096ac5c8ab6cc
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
(cherry picked from commit 5f871007d7)
Usually 'langmap' is used to map keyboard characters to ASCII motions or
mappings. It's not entirely clear what the purpose of mapping to Unicode
characters is, but since there is no error for mapping between two chars
both >= 256, only give a warning that this will not work properly when
mapping from a char < 256 to a char >= 256.
(cherry picked from commit 16c1334399)
`%*s` specifies the width limit, not the number of bytes.
In these places it doesn't matter as they are ASCII-only.
(cherry picked from commit 89960e27d6)
Problem: Division by zero in :file after failing to wipe buffer
(after 8.2.4631).
Solution: Still call buf_clear_file() when failing to wipe buffer
(zeertzjq).
closes: vim/vim#190881aa5ca4ecb
(cherry picked from commit 97bfc0c99b)
Problem: :edit and :enew may reuse a 1-line terminal buffer, causing
the new buffer to still be a terminal buffer.
Solution: Don't reuse a terminal buffer, as it's not reused when it has
more than 1 line.
After this change close_buffer() is the only place where buf_freeall()
can be called on a terminal buffer, so move the buf_close_terminal()
call into buf_freeall() to save some code. Furthermore, closing the
terminal in buf_freeall() is probably more correct anyway, as it is
"things allocated for a buffer that are related to the file".
Also, remove the useless check for on_detach callbacks deleting buffer.
Even if b_locked fails to prevent that, the crash will happen at the end
of buf_updates_unload() first. On the other hand, many other call sites
of buf_updates_unload() and other buffer_updates_* functions don't set
b_locked, which may be a problem as well...
(cherry picked from commit 23aa4853b3)
Problem: Crash when deleting terminal buffer and TermClose switches
back to the terminal buffer.
Solution: Set b_locked_split.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
(cherry picked from commit ad85871ca1)
Problem: Crash when deleting terminal buffer and TermClose deletes
other buffers.
Solution: Close the terminal after restoring b_nwindows.
(cherry picked from commit 7297e9d339)
Problem: Calling termopen() or nvim_open_term() on a buffer with an
existing terminal leads to two terminals writing to the same
buffer if the terminal job is still running, or memory leak
if the terminal job has exited.
Solution: Close the terminal if the terminal job has exited, otherwise
report an error.
Problem: Crash when closing a split window if autocmds close other
split windows but there are still floating windows.
Solution: Bail out and give the window back its buffer.
Problem: error set by win_set_buf may leak if autocommands immediately close the
new window.
Solution: free the error set by win_set_buf. (prefer nvim_open_win's error as
it's more important and will cause 0 to be returned)
Problem: split_disallowed seemingly exists to prevent issues from changing
frames to accomodate a split window, which doesn't apply to floats.
Solution: remove the restriction for nvim_open_win, but only for floats.
(continue to check b_locked_split though)
NOTE: like before, the buffer we check b_locked_split for may not actually be
the target buffer "buf", as the later call to win_set_buf can fail to switch to
"buf" due to autocommands. (among other things)
Maybe we could attempt to close the new window in that case (or switch to a
different buffer if that also fails), but this is safer. (and simpler)
Fixes#36857 (and possibly some spurious E242s I've observed from extui)
Problem: nvim_win_set_config may crash when attempting to move curwin to a
different tabpage if there is no other non-float available to switch to.
Solution: fix the crash. Fix ONE_WINDOW checks in winframe_find_altwin and
win_altframe to consider floating windows by instead using one_window. Allow
one_window to consider non-current tabpages. We can use one_window in
win_close_othertab now to also better reflect its use in win_close.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Problem: unlike win_close, win_close_othertab could be used to close the
autocommand window from a different tabpage. This causes aucmd_restbuf to close
the wrong window, potentially causing a crash.
Solution: disallow closing it. Also replace a deprecated use of exc_exec in the
test file.
Fixes#21409.
Problem: no check for nvim_open_win opening a new floating window into a closing
buffer, which can lead to crashes.
Solution: call check_split_disallowed; opening a new float semantically splits
from a window, so the same problems as regular splits apply. Also restore the
error if switch_win_noblock in win_set_buf fails (may not be possible to hit
this, but win_set_buf can silently succeed there since #31595).
As the lock check applies to curbuf (not the target buffer) this may feel a bit
restrictive, though this isn't different to how things like ":split" or
nvim_open_win with "split = true" works when targeting a different buffer. Only
checking the target buffer's lock will cause issues if win_set_buf doesn't end
up in the target buffer for whatever reason.
Maybe we could consider checking the lock of the buffer after win_set_buf and
close the window if it's locked (maybe a bit fiddly, especially as closing a
window can fail...), or make the open + switch operation more atomic, like how
Vim does for its popup windows..?
It also used to be the case that win_set_buf would set an error if autocommands
sent us to a different buffer than what was requested, but #31595 appears to
have also changed that... I haven't touched that here.
Problem: can't accurately know if close_buffer directly (e.g: not via autocmds)
decremented b_nwindows. This can cause crashes if win_close_othertab decides to
keep the window after calling close_buffer (if it did not free the buffer), as
b_nwindows may remain out-of-sync.
Solution: change the return value of close_buffer to accurately depict whether
it decremented b_nwindows. Check it in win_close_othertab to avoid a crash.
Similar issues may exist in other places that call close_buffer, but I've not
addressed those here (not to mention only one other place even checks its return
value...)
Problem: TabClosed is fired after close_buffer is called (after b_nwindows is
decremented) and after the tab page is removed from the list, but before it's
freed. This causes inconsistencies such as the removed tabpage having a valid
handle and functions like nvim_tabpage_get_number returning nonsense.
Solution: fire it after free_tabpage. Try to maintain the Nvim-specific
behaviour of setting `<amatch>` to the old tab page number, and the
(undocumented) behaviour of setting `<abuf>` to the buffer it was showing
(close_buffer sets w_buffer to NULL if it was freed, so it should be OK pass it
to apply_autocmds_group, similar to before).
Problem: No check for closing the only non-floating window in a non-current
tabpage that contains floats. This can lead to a tabpage that contains only
floats, causing crashes.
Solution: Copy the relevant check from win_close to win_close_othertab. Fix some
uncovered issues.
Closes#34943Fixes#31236
Co-authored-by: glepnir <glephunter@gmail.com>
In close_buffer(), free_buffer() is called to remove the buffer from
buffer_handles immediately after removing it from the buffer list, so as
long as a buffer is in buffer_handles it is always valid.
(cherry picked from commit 033302d97d)
Problem: Crash when a terminal receives OSC 2 just after closing its
buffer but before terminal job exits.
Solution: Remove FUNC_ATTR_NONNULL_ALL from buf_set_term_title() and
check for NULL.
(cherry picked from commit b67ac8cc6b)
Problem: null pointer member access when closing the only non-float in the
current tab page if autocommands after closing all floats also close all other
tab pages. (making it the last window)
Solution: check last_window again after closing the floats.
Also reduce the scope of "wp"; it would be bugprone to use it before it's later
reassigned to the rv of win_free_mem if freed by Buf/WinLeave.
(cherry picked from commit c14de47f1a)
Problem: Destroying a terminal with pending TermRequest leads to
heap-use-after-free when processing TermRequest afterwards.
Solution: Store the buffer handle instead of the Terminal pointer in the
pending TermRequest event, and don't emit TermRequest if the
terminal is already closed.