Problem: On MS-Windows it is not possible to switch to a buffer by name
with ":b" (including via command-line completion) when the
buffer name contains '%'.
Solution: Do not escape '%' and '#' for the ":buffer" command on
MS-Windows. Since ":buffer" has no EX_XFILE these are not
expanded, and escaping them as "\%"/"\#" makes buffer name
matching fail when '%'/'#' is in 'isfname' (the backslash is
treated as a path separator).
fixes: vim/vim#20529closes: vim/vim#205481a96e07bf6
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem: Crash with TextPut autocmd when pasting in normal mode in a
terminal buffer.
Solution: Skip the TextPut autocmds when reg and insert are both NULL
and regname is not '.' (Foxe Chen).
closes: vim/vim#204072e7833bde9
Co-authored-by: Foxe Chen <chen.foxe@gmail.com>
Problem:
:Man does not syntax highlight codeblocks (injected language).
Analysis:
init_pager() swapped pcall(parse_ref, ref) return values order, so
vim.b.man_sect was set to the manpage name instead of the section
number, so C syntax highlighting did not load.
Solution:
Swap the calls.
Problem:
- Transient mutation of the parent env is visible to any concurrent
code. Or at least just kinda sloppy.
- Latent bug:`channel_job_start` queues the spawn and returns before
`uv_spawn` runs, so the prior `os_unsetenv` immediately after the call
could in principle race with the deferred spawn.
Solution:
Pass `env` to the channel.
Today there is a constraint that these arguments to the enable filter be
mutually exclusive, but I do not know why such a constraint exists (it
is perfectly reasonable to want to enable a capabilility for just one
buffer and just one client).
Problem: [security]: s:NetrwLocalRmFile() escapes only the backslash in
the file name before passing it to :execute, so a name
containing "|" injects arbitrary Ex commands when the file is
deleted (cipher-creator)
Solution: Use fnameescape() to correctly escape the file name
(Yasuhiro Matsumoto).
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-vhh8-v6wx-hjjh
Supported by AI
55bc757a5d
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Problem: [security]: a crafted spell file with a self-referential
BY_INDEX node in the prefix tree can drive dump_prefixes()
past the end of its MAXWLEN-sized depth arrays on :spelldump
(cipher-creator)
Solution: only descend while depth < MAXWLEN - 1, as the sibling trie
walkers already do (Yasuhiro Matsumoto)
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-qm9w-fmpj-879h
Supported by AI
8325b193bb
Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Problem: When defining a dictionary function, the function name string
is allocated with vim_strnsave() but the result is not
checked. On allocation failure the dict entry is left with
type VAR_FUNC and a NULL name, and in the overwrite case the
previous entry has already been freed before the NULL is
stored.
Solution: Allocate the name before modifying the dict entry and bail out
on failure, freeing it on all error paths (thinca)
closes: vim/vim#203762b2dfc4f5a
Co-authored-by: thinca <thinca@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Problem: ins_compl_equal_sc() uses MB_TOLOWER() on single bytes, but
it indexes raw bytes, not decoded characters (after v9.1.0651).
Solution: Use TOLOWER_LOC(), matching what STRNICMP()/ins_compl_equal()
does (glephunter).
closes: vim/vim#205359f5d32cf5c
Co-authored-by: glepnir <glephunter@gmail.com>
Problem: With 'longest', 'smartcase' is ignored when filtering matches:
"inp" offers only "InputEvent", and an uppercase pattern gives
different results for CTRL-N and CTRL-P.
Solution: 'longest' rewrites the leader with the common prefix, picking
up uppercase the user never typed. Judge case from the typed
text instead, and match the auto-inserted part of the leader
case-insensitively so CTRL-N and CTRL-P give the same result.
(glepnir)
related: neovim/neovim#40259
closes: vim/vim#2053350fe45aca7
Co-authored-by: glepnir <glephunter@gmail.com>
Problem:
Can't open swapfile when using a device path starting with `//?/`,
because `?` is a reserved char on Widnows.
Solution:
For device UNC paths, replace `//?/UNC/` and `//./UNC/` with `//`.
For other device paths, just strip their prefix (i.e. `//?/`, `//./`).
This aligns swapfile naming for device paths with regular UNC and DOS
paths.
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
All wasm parsers shared a single global TSWasmStore via
ts_parser_set_wasm_store(). A TSWasmStore is owned by exactly one parser:
ts_parser_delete() frees it through ts_wasm_store_delete(). So the first
wasm parser collected freed the shared store, leaving the global pointer
dangling, and creating the next wasm parser dereferenced freed memory in
ts_wasm_store_reset() -> wasmtime_store_context(), crashing with SIGSEGV.
Give each parser its own store via ts_wasm_store_new() instead. This is
the 1:1 store-per-parser model intended by tree-sitter (see
tree-sitter/tree-sitter#3454): the global store remains only as the
language loader, ts_parser_delete() cleanly frees each parser's own
store, and the wasm engine is shared safely because ts_wasm_store_new()
clones its engine reference internally.
AI-assisted: Claude Code
Problem:
A colored (guisp) underline showing through a 'winblend' float
lost its special color and followed the foreground instead.
Solution:
In the blend-through case, blend the underline's special color
only when the cell below sets sp explicitly; otherwise clear it.
Problem: Coverity complains about Null pointer dereferences
Solution: before accessing ccline->cmdbuff check that ccline is not NULL
Fixes: Coverity issue 1646601
closes: vim/vim#17189362be6ba27
Co-authored-by: Christian Brabandt <cb@256bit.org>
vim-patch:9.2.0641: GTK4: crash in gui_mch_menu_hidden()
vim-patch:47bb4bed4 editorconfig: don't change spaces to tabs in git commit message
vim-patch:9.2.0644: popup image: duplicate sync-output code
vim-patch:9.2.0646: GTK3 GUI slow on HiDPI/4K with software rendering
vim-patch:9.2.0650: Vim aborts at startup when built with the example -O2 CFLAGS
vim-patch:9.2.0652: popup: stale kitty image after clipwindow scrolls out of view
vim-patch:9.0.1865: Vim9: garbage collection may cause crash
vim-patch:9.1.0481: Vim9: term_getjob() throws an exception on error
vim-patch:9.1.0625: tests: test output all translated messages for all translations
vim-patch:9.1.0682: Vim9: Segfault with uninitialized funcref
vim-patch:9.1.1225: extra NULL check in VIM_CLEAR()
vim-patch:9.1.1696: tabnr from getwininfo() for popup windows is always 0
vim-patch:9.1.2113: potential NULL pointer dereference issues
vim-patch:9.2.0648: MS-Windows: Compile warnings
Problem: [security]: a crafted spell file can drive tree_count_words()
past the end of its MAXWLEN-sized depth arrays; the descent
loop has no depth bound.
Solution: only descend while depth < MAXWLEN - 1, as the sibling trie
walkers already do; apply the same guard to sug_filltree().
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-wgh4-64f7-q3jq
Supported by AI.
a80874d9b8
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: Coverity warns for using a NULL pointer.
Solution: Check for memory allocaion failure.
96cbbe29de
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit makes processing the erlangOperator and erlangBitType syntax
items faster.
- erlangOperator changes:
- Vim now parses erlangOperator faster because we define the operators
individually.
- The order of operators in erlangOperator had to be changed to make
the edge cases work the same as before (for example
erlangEqualsBinary).
- erlangBitType changes:
- Vim now parses erlangBitType faster because:
1. Now the long `\%(integer\|float\|...\)` sections are preceded by
"beginning of word" patterns (`\<`).
2. Now we use the old regexp engine (`\%#=1`).
Previously when an Erlang file contained long lines with erlangOperator
or erlangBitType patterns near the end, redrawing these lines was slow,
and typing at the end of the line was also slow.
For example, redrawing a 1787 characters long test line is now roughly
six times faster.
fixes: vim/vim#5593closes: vim/vim#20524c6705b2c3e
Co-authored-by: Csaba Hoch <csaba.hoch@gmail.com>
Problem:
an empty `{ isIncomplete = true, items = {} }` ends completion
instead of requerying.
Solution:
keep isIncomplete on empty lists and retrigger on keypress while incomplete.
Reset on <C-e> so it doesn't immediately re-query.
Problem: a font set via nvim_set_hl is lost or corrupted with font-only groups,
attribute combining, and update=true, and is dropped on any attr-table rebuild.
nvim__inspect_cell also frees the font name while a returned dict still borrows it.
Solution: register font-only groups, carry font through hl_combine_attr, inherit
it on update, and persist sg_font so a rebuild can restore it. Keep interned font
names across a rebuild instead of clearing them. Add the missing font field to
get_hl_info.
Co-authored-by: Ryan Patterson <cgamesplay@cgamesplay.com>
Problem:
'autoread' error if file goes missing.
E211: File "runtime/lua/nvim/autoread.lua" no longer available
vim.schedule callback: /usr/local/share/nvim/runtime/lua/nvim/autoread.lua:146:
Vim:E211: File "test/functional/options/autoread_spec.lua" no longer available
stack traceback:
[C]: in function 'checktime'
/usr/local/share/nvim/runtime/lua/nvim/autoread.lua:146:
in function </usr/local/share/nvim/runtime/lua/nvim/autoread.lua:138>
Solution:
Ignore E211 thrown by `:checktime`.
Problem: vim.diagnostic.Opts.VirtualLines.current_line and
vim.diagnostic.Opts.VirtualText.current_line cause redraw
on every CursorMoved event that makes the text jump
uncomfortably with rapid cursor movement.
Solution: `current_line` state is applied only on CursorHold,
while still being cleared on CursorMoved making it so that
until the cursor has stopped on a line, its diagnostic
looks like cursor is not on the line preventing flicker.
Problem:
This test is flaky since fff9897ce3 :
FAILED ...Xtest_xdg_terminal/test/functional/terminal/tui_spec.lua @ 4359:
TUI bg color does not trigger OptionSet from automatic background processing
Expected values to be equal.
Expected:
{ true, 0 }
Actual:
{ true, 1 }
stack traceback:
...Xtest_xdg_terminal/test/functional/terminal/tui_spec.lua:4380:
in function <...Xtest_xdg_terminal/test/functional/terminal/tui_spec.lua:4359>
`apply_optionset_autocmd_now` does not emit `OptionSet` during startup:
void apply_optionset_autocmd_now(...) {
// Don't do this while starting up, failure or recursively.
if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) {
return;
}
...
}
but if OSC 11 response arrives AFTER VimEnter, then
`nvim_set_option_value('background',…)` call triggers `OptionSet`.
Solution:
Use `:noautocmd` when setting 'background'.
Per fff9897ce3, OSC11 is not intended to trigger OptionSet.
fix https://github.com/neovim/neovim/issues/40235
Problem: The refactor to use Capability left around some cruft and
semi-broken configuration for debounce.
Solution: Clean up now-unnecessary helper methods and simplify
deprecated ones to pass through to the non-deprecated ones. `debounce`
now defaults to 200 for all buffers but is overridable via the
deprecated start() method, which continues to take the max value
specified for any client attached to the buffer.
If we wish to expose changing the debounce in a non-deprecated way, we
will need to consider a "configuration" function, or even a bespoke
method to set the debounce time on the main metaclass (or provide
options to override for a particular buffer). General configuration of
specific LSP features is an as-of-yet unsolved problem.
Problem:
On Windows and macOS, entries in `oldfiles` may differ only in case,
but actually refer to the same file.
Solution:
Previously, deduplication used `Set_cstr_t`. We can add a similar `Set_path_t`
that performs path-aware comparisons, ignoring case differences. On Windows, it
could also ignore path separator differences, and treat `C:\foo` and `\foo` as
the same path when the current drive is `C:`.
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Problem:
On some non-US keyboards, like Estonian/Swedish/etc, widely used []
characters in vim are hard to type. One way to overcome this is to use langmap
option to map accented characters, that are in the same place as [] on US
keyboards to []. Unfortunately this does not work currently in neovim, it
cannot map multibyte characters via langmap.
Solution:
The fix iterates over characters in typeahead and key buffers, instead of bytes,
in getchar.c handle_mapping(). It does not handle macros though, these tests are
still failing when turned on.
Closes#2420Closes#27776
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Problem: filetype: tf files sometimes incorrectly recognized
(Christian Robinson)
Solution: Add support for g;filetype_tf variable to override detection,
re-write the filetype detection loop
closes: vim/vim#20510
Supported by AI
522a39a489
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: When a candidate gets truncated to MATCH_MAX_LEN and ends up
the same length as the needle, the n == m shortcut would
return SCORE_MAX with positions 0..n-1, even if the strings
actually differ.
Solution: Only use the shortcut if the truncated strings are truly equal.
Otherwise, fall back to regular matching.
Example:
echo matchfuzzypos(['x' .. repeat('a',1024)], repeat('a',1024))
closes: vim/vim#204751437f47815
Co-authored-by: glepnir <glephunter@gmail.com>
Problem: Coverity warns about NULL pointer when triggering WinResized
Solution: Add OOM checks for windows_list like for scroll_dict. Remove
void casts that are unnecessary after 9.1.1084 (zeertzjq).
closes: vim/vim#16959b42b9fc41f
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Problem: Problem with initializing the length of range() lists
Solution: Set length explicitly when it shouldn't contain any items
range() may cause a wrong calculation of list length, which may later
then cause a segfault in list_find(). This is usually not a problem,
because range_list_materialize() calculates the length, when it
materializes the list.
In addition, in list_find() when the length of the range was wrongly
initialized, it may seem to be valid, so the check for list index
out-of-bounds will not be true, because it is called before the list is
actually materialized. And so we may eventually try to access a null
pointer, causing a segfault.
So this patch does 3 things:
- In f_range(), when we know that the list should be empty, explicitly
set the list->lv_len value to zero. This should happen, when
start is larger than end (in case the stride is positive) or
end is larger than start when the stride is negative.
This should fix the underlying issue properly. However,
- as a safety measure, let's check that the requested index is not
out of range one more time, after the list has been materialized
and return NULL in case it suddenly is.
- add a few more tests to verify the behaviour.
fixes: vim/vim#13557closes: vim/vim#13563
--------
Vim9 (non) materialize list is N/A.
Port only tests.
df63da98d8
Co-authored-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Tim Pope <tpope@github.com>
Problem: Vim9: concatenating to a NULL list doesn't work.
Solution: Handle a NULL list like an empty list. (closesvim/vim#7064)
1a73923705
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: statusline: buffer overflow with item groups
Solution: Fix the issues (see below) (Sébastien Hoffmann)
Fix various buffer overflow bugs (examples assume MAXPATHL==4096):
- truncated item groups where minwid>maxwid:
vim --clean +"set ls=2 stl=%<%{%repeat('x',4096-11)%}%50.5(12🙂345%)"
leads to fillchars spilling over the end of the group/buffer while trying to
compensate for truncating at a multicell character because minwid<=maxwid is assumed
- left-aligned item groups with multi-byte fillchar:
vim --clean +"set ls=2 fillchars+=stl:∙ stl=%<%{%repeat('x',4096-3)%}%-2(X%)"
wrongly leads to padding at the end of the statusline and `p-out==4097`
because the bounds check assumes a 1-byte fillchar
- right-aligned item groups with 1-byte fillchar:
vim --clean +"set ls=2 stl=%<%{%repeat('x',4096-4)%}%4(XY%)"
leads to "YX" instead of "XY" at the end of the statusline
because `memmove` is done before adjusting the offset
- right-aligned item groups with multi-byte fillchar:
vim --clean +"set ls=2 fillchars+=stl:∙ stl=%5(X%)"
leads to "∙∙∙∙<e2>", i.e. the fillchar is being written over the group contents
and eventually being overwritten itself at the second byte with the final NUL,
because the padding counter assumes a 1-byte fillchar; to crash vim,
vim --clean +"set ls=2 fillchars+=stl:∙ stl=%<%{%repeat('x',4096-149)%}%50(X%)"
related: neovim/neovim#40219
closes: vim/vim#20522d249884340
Co-authored-by: Sébastien Hoffmann <contact@shoffmann.dev>
Problem: Composing chars are no longer accepted in end-id abbreviation
(after 9.2.0629).
Solution: Unescape all chars using vim_unescape_csi() instead of using
mb_unescape() on individual chars, so that mb_ptr2len() and
MB_PTR_ADV() can still be used.
closes: vim/vim#2051423a84d28a8
Problem: 0x80 and 0x9b byte not unescaped when checking for valid abbr
(Mao-Yining)
Solution: Use mb_unescape() (zeertzjq).
fixes: vim/vim#20506closes: vim/vim#205081958c991a8
Problem:
Any random ftplugin or other autocmd, can throw an error when
`:checktime` reloads a buffer. This causes a trace which makes it look
like an issue with `autoread.lua`.
vim.schedule callback: …/runtime/lua/nvim/autoread.lua:146:
FileType Autocommands for "*"..function <SNR>1_LoadFTPlugin[20] ..script
…/runtime/ftplugin/help.lua: Vim(runtime):E5113: Lua chunk:
…/runtime/lua/vim/treesitter.lua:216: Index out of bounds
stack traceback:
[C]: in function 'nvim_buf_get_text'
…/runtime/lua/vim/treesitter.lua:216: in function 'get_node_text'
…/runtime/lua/vim/treesitter/query.lua:558: in function 'handler'
…/runtime/lua/vim/treesitter/query.lua:843: in function '_match_predicates'
…/runtime/lua/vim/treesitter/query.lua:1082: in function '(for generator)'
…/runtime/ftplugin/help.lua:91: in function 'runnables'
…/runtime/ftplugin/help.lua:124: in main chunk
[C]: in function 'checktime'
…/runtime/lua/nvim/autoread.lua:146: in function <…/runtime/lua/nvim/autoread.lua:138>
Solution:
Use pcall() and surface the error via nvim_echo.