commit e3c36f31e3a0863db0458c339eddf6e22cf0c2ec
parent a0c60e819df1b4d4ae5ac631d48e874fa1cf9b92
Author: skewb1k <skewb1kunix@gmail.com>
Date: Sat, 27 Sep 2025 05:32:28 +0300
fix(highlight): ensure extmark range is within buffer bounds #35928
Adds an additional check for the case when end_col = 0, addressing
https://github.com/neovim/neovim/issues/35814#issuecomment-3340709532.
Validation is now localized to the highlighter without affecting the C API.
Diffstat:
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
@@ -443,17 +443,22 @@ local function on_range_impl(
local url = get_url(match, buf, capture, metadata)
if hl and not on_conceal and (not on_spell or spell ~= nil) then
- api.nvim_buf_set_extmark(buf, ns, start_row, start_col, {
- end_line = end_row,
- end_col = end_col,
- hl_group = hl,
- ephemeral = true,
- priority = priority,
- conceal = conceal,
- spell = spell,
- url = url,
- _subpriority = subtree_counter,
- })
+ -- Workaround for #35814: ensure the range is within buffer bounds,
+ -- allowing the last line if end_col is 0.
+ -- TODO(skewb1k): investigate a proper concurrency-safe handling of extmarks.
+ if (end_row + (end_col > 0 and 1 or 0)) <= api.nvim_buf_line_count(buf) then
+ api.nvim_buf_set_extmark(buf, ns, start_row, start_col, {
+ end_row = end_row,
+ end_col = end_col,
+ hl_group = hl,
+ ephemeral = true,
+ priority = priority,
+ conceal = conceal,
+ spell = spell,
+ url = url,
+ _subpriority = subtree_counter,
+ })
+ end
end
if
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
@@ -813,8 +813,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
len = opts->ephemeral ? MAXCOL : ml_get_buf_len(buf, (linenr_T)line2 + 1);
} else if (line2 == buf->b_ml.ml_line_count) {
// We are trying to add an extmark past final newline
- // TODO(skewb1k): workaround for #35814. Investigate proper concurrency-safe handling of extmarks.
- len = opts->ephemeral ? MAXCOL : 0;
+ len = 0;
} else {
// reuse len from before
line2 = (int)line;