Problem: When termguicolor is set, popup opacity seems reversed
for the underlying text: when opacity go from 1 to 99,
the greater opacity is, the more underlying text is readable.
Solution: Invert popup_color and base_fg when calling blend_colors
(Shad).
fixes: #20283closes: #20284
Signed-off-by: Shad <shadow.walker@free.fr>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: quickfix: can set quickfixtextfunc in restricted/sandbox mode
(tacdm)
Solution: Disallow setting the quickfixtextfunc option from a sandbox
and restricted mode (Yegappan Lakshmanan).
closes: #20305
Co-Authored-by: tacdm
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: [security]: memory safety issues in spellfile.c
(tacdm)
Solution: Add recursion limit to read_tree_node(), add length limit
check in tree_count_words(), use alloc_clear() in
spell_read_tree().
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-3h95-3962-mmvf
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: clientserver feature uses binary protocol and is hard
to understand
Solution: Rewrite the code based on channels and JSON messages
(Foxe Chen).
closes: #19782
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: setline() insert mode mapping may trigger autoindent,
corrupting the newly inserted line content (Evgeni Chasnovski)
Solution: Only strip autoindent whitespace when the rest of the line is
all whitespace (glepnir).
fixes: #19363closes: #20290
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: completion: cannot complete user cmd :K with 'ignorecase'
(rendcrx)
Solution: Skip the short-circuit when 'ignorecase' is set
(Yasuhiro Matsumoto)
The set_cmd_index() short-circuit for the :k command treats ":k<X>" as
":k {X}" (mark argument), which makes ":kz<Tab>" never reach the
command-name expansion path. With 'ignorecase' the same prefix on other
letters (":gz<Tab>") completes a user command like :Gz, so the result is
inconsistent. Skip the short-circuit when 'ignorecase' is set; default
behaviour is preserved so the existing :k tests still pass.
fixes: #20241closes: #20275
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When a public member and a protected member in a Vim9
class have the same name (differing only in the leading '_'),
Vim reports E1369 "Duplicate variable", which is also used for
plain duplicate definitions. Users cannot tell from the
message whether the conflict is the public/protected naming
rule or a real duplicate.
Solution: Add a dedicated error E1406 "Public and protected member
have the same name" and emit it only when the name clash is
between a public and a protected member. Keep E1369 for
genuine duplicate variable definitions (Hirohito Higashi).
fixes: #20240closes: #20277
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: To goto or delete a bookmark, one needs to prefix a count
for the bookmark number (e.g., "2gb" to open bookmark#2).
As the bookmark list gets or deletes entries, the numbers
keep changing, requiring listing the bookmarks with qb to
discover the desired bookmark number. Typing gb or mB
without a count targets g:netrw_bookmarklist[-1].
Solution: If no count is given to gb or mB, list all bookmarks and
prompt for a number using inputlist(), similar to tag jump
with g].
closes: #20211
Signed-off-by: J. Paulo Seibt <jpseibt@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: filetype: some html files are wrongly recognized as htmlangular
Solution: Use the \< atom to anchor ng-template and ng-content to start
of word (truffle)
Prevent false-positive htmlangular detection on words containing
'ng-template' or 'ng-content' as a substring (e.g. 'song-template',
'sing-content'). Anchor both branches with \< to require a word start,
matching the \<DTD\s\+XHTML\s idiom used five lines below.
related: neovim/neovim#39778.
closes: #20246
Signed-off-by: truffle <truffleagent@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Continue using "strwidth" when calculating the position of
a column of interest, and start using "setcharpos" when
marking a line of interest so that paired-up marks remain
aligned columnwise across all three parts generated by
"term_dumpdiff", especially when multibyte characters are
written in the line before the marked column.
closes: #20237
Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Cannot disable modeline processing when loading a file
(Mao-Yining, after v9.2.0350)
Solution: Allow to disable modeline processing even when
'modelienstrict' is in effect.
fixes: #20103closes: #20229
Signed-off-by: Christian Brabandt <cb@256bit.org>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: [security]: runtime(netrw): code injection via
NetrwBookHistSave()
Solution: Properly quote the directory name using string() function
(Srinivas Piskala Ganesh Babu)
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-crm5-rh6j-2c7c
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: User commands cannot handle single args with spaces
Solution: Add the -nargs=_ attribute (Maxim Kim)
-nargs=_ allow user commands to have a single argument with spaces.
For example given the following Test command and TestComplete function:
```
vim9script
def TestComplete(A: string, _: string, _: number): list<string>
var all = ["qqqq", "aaaa", "qq aa"]
return all->matchfuzzy(A)
enddef
command! -nargs=_ -complete=customlist,TestComplete Test echo <q-args>
```
`:Test q a<tab>` should successfully complete `qq aa`
fixes: #20102closes: #20189
Signed-off-by: Maxim Kim <habamax@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup: missing Popup, PopupBorder and PopupTitle highlight groups
Solution: add Popup, PopupBorder and PopupTitle highlight groups and
fall back to Pmenu related highlighting groups (Yasuhiro Matsumoto).
fixes: #20110closes: #20208
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: matchfuzzy() can crash on long multi-word patterns.
Solution: Clamp pat_chars to maxMatches and stop before calling
match_positions() when the buffer is full (glepnir).
closes: #20209
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Parentheses are not part of the function name so highlight them
differently.
closes: #20219
Signed-off-by: Doug Kearns <dougkearns@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: filetype: some Objective-C files are not recognized
Solution: Add g:filetype_mm override variable, improve the objective c
pattern detection (Keith Smiley).
closes: #20221
Signed-off-by: Keith Smiley <keithbsmiley@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When two windows are placed side by side with vsplit and
their status lines are connected (the cell between them
is drawn with the 'stl' / 'stlnc' fillchar, not the
'vert' character), that connecting cell still uses the
VertSplit highlight. The status line bar therefore
looks broken at the separator column, and any custom
edge highlight set in 'statusline' (%#XX# / %N*) is cut
off there.
Solution: Make that connecting cell take the highlight from the
neighbouring status line edge instead of VertSplit:
- Next to the current window, use the current
window's edge highlight, so the StatusLine bar (and
any %#... at the edge) extends into the column
without a seam.
- Between two non-current windows whose status
fillchar is a space, use the left window's
right-edge highlight, so the StatusLineNC bar is
continuous across the column too.
Cells drawn with the 'vert' character (the two windows
do not share a status line) keep the VertSplit
highlight as before.
Add Test_statusline_vsep_borrow_hl with two layouts
(NC | cur | NC | NC and NC | NC | cur | NC) so all
three cases above are covered.
closes: #20182
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: out-of-bound read when recovering corrupted swap files
(Rahul Hoysala)
Solution: Validate the db_txt_start field when recovering a swap
file.
Supported by AI
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: clipboard provider callback can be called recursively, leading
to E132: Function call depth is higher than 'maxfuncdepth'
Solution: Prevent recursive calls of
clip_provider_copy()/clip_provider_paste() (Foxe Chen).
closes: #20213
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: TextPutPre triggers clipboard provider callback twice
when do_put() runs autocommands that themselves request
the clipboard.
Solution: Guard do_put() and put_do_autocmd() with
inc_clip_provider()/dec_clip_provider() so the provider
is queried at most once per put operation (Foxe Chen).
closes: #20215
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When a terminal buffer is shown inside a popup with 'opacity'
set to a value other than 100, typing into it freezes Vim.
Only the first keystroke is drawn; afterwards no input is
processed and the screen stops updating.
Solution: When marking background lines for redraw to keep opacity
blend cells fresh, do not raise must_redraw. This marking
happens from inside update_screen() (via
may_update_popup_mask()), so raising must_redraw makes
terminal_loop()'s "while (must_redraw != 0) update_screen()"
loop never terminate. Add redraw_win_range_now() that
updates only the per-window state and use it from
redraw_win_under_opacity_popup() (Hirohito Higashi)
fixes: #20214closes: #20220
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: runtime(netrw): command injection possible via crafted
directory names in NetrwMaps() (Christopher Lusk)
Solution: Temporarily remove B flag in NetrwMaps() to prevent command
injection
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup_mask still marks the freed popup's cells as covered
until may_update_popup_mask() runs inside the next
update_screen. Any screen_fill / screen_puts called in
between (for example msg_clr_eos triggered by a status message
from :copen) hits skip_for_popup() and silently drops writes
to those cells, so the popup's chars survive on screen until
those cells happen to be redrawn for another reason.
Solution: Add popup_clear_mask_for() and call it from popup_hide() and
popup_free() when the popup was visible, so the upcoming
writes take effect immediately (Yasuhiro Matsumoto)
Note: The test is limited to MS-Windows because the original report
(#20178) was reproduced there and the redraw timing required to
surface the bug differs on other platforms.
fixes: #20178closes: #20188
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: the bookmarks list can have duplicate entries, more often
in win32 (due to mixed slashes and capitalization) and when
g:netrw_keepdir=0 (which could introduce relative paths).
Duplicate entries could be: C:\foo\BAR\baz.file
c:\foo\bar\baz.file
c:/foo\BAR/baz.file
BAR/baz.file
Solution: Normalize the paths and make sure they are always absolute
(J. Paulo Seibt).
closes: #20194
Signed-off-by: J. Paulo Seibt <jpseibt@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Pasting ". register without TextPut* autocommands breaks
subsequent TextPut* autocommands (after 9.2.0470).
Solution: Only decrement add_last_insert if it has been incremented
(zeertzjq).
closes: #20192
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: No way to hook into put commands
(yochem)
Solution: Introduce TextPutPre and TextPutPost autocommands
(Foxe Chen).
fixes: #18701closes: #20144
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: A popup anchored to a text property in a split window is
positioned relative to the screen and may extend into
adjacent splits or off-screen regions. There is no way to
confine the popup to the window that contains the textprop.
Solution: Add the "clipwindow" popup option to allow clipping the text
property popup to the host window (Yasuhiro Matsumoto).
Adds a "clipwindow" boolean option to popup_create()/popup_setoptions().
When set on a textprop-anchored popup, the popup's drawn extent is
confined to its host (textprop) window's content rectangle so the popup
no longer bleeds across a horizontal split's statusline (top/bottom) or
a vsplit's separator (right) into another window.
The popup keeps its full logical size and position; only the rows or
columns that fall outside the host window's content area are skipped
during drawing, so a popup that scrolls toward the host's edge looks
visually "cut off" without its borders being relocated. popup_getoptions
and popup_getpos continue to report the unclipped geometry.
Implementation:
- w_popup_topoff / w_popup_bottomoff record how many rows of the
popup fall outside the host on each side. popup_adjust_position()
computes them from the host rectangle after the logical layout is
finalised, and update_popups() and the popup-mask builder subtract
them when emitting cells/borders/scrollbar and when marking
popup-owned cells. win_update() is bracketed by transient
w_height/w_topline/w_winrow adjustments so the buffer's drawn
content matches the visible row range.
- w_popup_rightclip is the horizontal counterpart for the host's
right edge: the right border, padding and content columns past
the host are not drawn. win_update() is bracketed by a transient
w_width reduction so the buffer text is not written past the
host's right edge either.
- When the textprop scrolls just above the host window's top, the
popup is kept visible by extending the prop search above topline
(new helper find_prop_in_lines) and synthesising a negative
screen_row so the top-clip path can roll the popup off the top.
When the textprop has scrolled far enough that even the bottom
border would overlap the host edge -- or when the popup would
overflow the host's left edge at all -- the popup is hidden, and
unhidden again once it comes back within range.
- The "reduce-height" / "clamp winrow to 0" fallbacks in
popup_adjust_position are bypassed for host-clipped popups so the
popup keeps its natural anchored position instead of being
snapped to the screen edge.
Left-edge partial clipping is intentionally not supported: it
would require shrinking the buffer width during win_update, which
reflows wrapped lines and corrupts the displayed content; the
popup is hidden instead.
closes: #20166
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup_show() from a CmdlineChanged autocommand doesn't update
the screen (Mao-Yining)
Solution: Refresh the screen when popups need redraw
(Yasuhiro Matsumoto).
popup_settext()/popup_show() called from a CmdlineChanged autocommand
did not refresh the screen because cmdline mode normally skips
update_screen(), so async info-popup updates only became visible after
a manual :redraw. Refresh the screen when popups need redrawing right
after the autocommand.
fixes: #20175closes: #20179
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: In a multi-line statusline (and 'tabpanel'), %#XX# / %N*
set on one row do not persist on subsequent rows.
build_stl_str_hl_local() rebuilds stl_items[] from scratch
on every line break ("%@" or "\n"), so the highlight is
reset at each row boundary even though within a row it
stays until %* (or another %# / %*).
Solution: Carry the last Highlight item's stl_minwid across line
breaks via a new in/out int* parameter "carry_hl". At the
start of each row, pre-insert a Highlight item from the
carried value so the row begins under the same highlight;
before returning, update the carried value with the row's
final Highlight item. Apply the same carry to the
tabpanel rendering loop (Hirohito Higashi).
related: #19123
closes: #20180
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: popup: redraw can use stale blended cells
Solution: Save the old popup area and redraw the newly exposed region so
opacity popups don't show stale blended cells when another
popup moves or closes. Consolidate redraw helpers so the
saved-area and exposed-area logic is shared across
move/hide/close/settext/setoptions. Refactor popup redrawing
code, add a regressions tests (Yasuhiro Matsumoto).
closes: #20172
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: modeline: foldmarker cannot be set with modelinestrict
(Lyderic Landry, after v9.2.0350)
Solution: Add foldmarker option to the whitelist
fixes: #20028closes: #20174
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: runtime(netrw): bookmarking directory uses current dir
Solution: Correctly handle netrw actual directory (J. Paulo Seibt)
fixes: #10481closes: #20169
Signed-off-by: J. Paulo Seibt <jpseibt@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Not able to use legacy expression evaluation in a vim9script
maps
Solution: Explicitly set script version to 1 when the :legacy modifier has been
used (Yegappan Lakshmanan).
fixe: #20176closes: #20177
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: The four pointer-resolution loops in u_read_undo() lack
an i != j guard, so a header whose uh_next.seq equals
its own uh_seq resolves uh_next.ptr to itself. On
buffer close, u_freeheader() sees uhp->uh_next.ptr !=
NULL and skips updating b_u_oldhead, so u_blockfree()
dereferences the freed header on the next iteration.
The same pattern applies to uh_prev, uh_alt_next and
uh_alt_prev. A crafted .un~ file in the same directory
as a text file can trigger the use-after-free and
subsequent double-free when the buffer is closed.
(Daniel Cervera)
Solution: Add an i != j guard to each of the four resolution
loops, matching the guard already present in the
duplicate-detection loop above.
closes: #20168
Supported by AI
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: tests: test_termcodes fails, because it disabled DECRQM, but
did not adjust the expected values in the test (after v9.2.0456)
Solution: Update the test
related: #20161
closes: #20173
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Crash with invalid shellredir/shellpipe value
(bfredl)
Solution: Validate the option and allow only a single "%s".
fixes: #20157closes: #20159
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: 'findfunc' only allows extra info for cmdline completion, not
for actually finding files (Maxim Kim, after 9.2.0451).
Solution: Handle returning a list of dicts when actually finding files.
Also fix crash on NULL string (zeertzjq).
fixes: #20163closes: #20164
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: No test that "abbr" in customlist completion is shown in pum.
Solution: Add some "abbr" fields to the existing test (zeertzjq).
closes: #20165
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Since v9.2.0349, the vertical separator cell at status line
rows is drawn as a space with StatusLine highlight, hiding the
user's 'fillchars' "vert" or "stl"/"stlnc" character at that
cell (after v9.2.0349)
Solution: Drop the status line blend. At status line rows the separator
cell goes back to using the status fillchar when adjacent
status lines are connected, or the vsep character otherwise.
(Same as before v9.2.0348)
Keep the VertSplitNC highlight group introduced in v9.2.0349. The
highlight (VertSplit vs VertSplitNC) is selected based on whether the
current window is adjacent to the separator at the row.
Vertical separators are redrawn on current-window changes and on
:redrawstatus[!] so the VertSplit/VertSplitNC highlight is updated
immediately.
fixes: #20089
related: #19951
closes: #20167
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: 'findfunc' can't return extra info for cmdline completion
(Maxim Kim).
Solution: Handle 'findfunc' return value in cmdline completion like that
of "customlist" functions (zeertzjq).
fixes: #20155closes: #20158
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: read_compound() in spellfile.c computes the size of the regex
pattern buffer using signed-int arithmetic on the attacker
controlled SN_COMPOUND sectionlen. With sectionlen=0x40000008
and UTF-8 encoding active the multiplication wraps to 27 while
the per-byte loop writes up to ~1B bytes, overflowing the heap.
Reachable when loading a crafted .spl file (e.g. via 'set spell'
after a modeline sets 'spelllang'). The cp/ap/crp allocations
have the same int + 1 overflow class (Daniel Cervera)
Solution: Use type size_t as buffer size and reject values larger than
COMPOUND_MAX_LEN (100000). Apply the same size_t treatment to
the cp/ap/crp allocations.
Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-q4jv-r9gj-6cwv
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: Vim9: dangling cmdline pointer after skip_expr_cctx()
(Foxe Chen)
Solution: Extract the cmdline restoration logic from compile_lambda into
a helper restore_cmdline_arg() and call it from
skip_expr_cctx() too, so a skipped lambda inside an "else"
branch does not leave "*arg" pointing into freed evalarg
memory (Yasuhiro Matsumoto).
fixes: #20147closes: #20148
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Problem: When find_start_brace() scans backwards for the enclosing
block, '{' and '}' inside // and /* */ comments are counted,
producing wrong indent for code following such comments
(rendcrx).
Solution: Implement FM_SKIPCOMM in findmatchlimit() to track block-
comment state and skip matches inside comments. Pass
FM_SKIPCOMM from cindent's call sites
(find_start_brace, find_match_char, cin_iswhileofdo,
get_c_indent).
fixes: #4
fixes: #648
fixes: #19578closes: #19581closes: #20111
Signed-off-by: magnus-rattlehead <guranjakustivi@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>