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.
This commit is contained in:
skewb1k
2025-09-27 05:32:28 +03:00
committed by GitHub
parent a0c60e819d
commit e3c36f31e3
2 changed files with 17 additions and 13 deletions

View File

@@ -443,17 +443,22 @@ local function on_range_impl(
local url = get_url(match, buf, capture, metadata) local url = get_url(match, buf, capture, metadata)
if hl and not on_conceal and (not on_spell or spell ~= nil) then 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, { -- Workaround for #35814: ensure the range is within buffer bounds,
end_line = end_row, -- allowing the last line if end_col is 0.
end_col = end_col, -- TODO(skewb1k): investigate a proper concurrency-safe handling of extmarks.
hl_group = hl, if (end_row + (end_col > 0 and 1 or 0)) <= api.nvim_buf_line_count(buf) then
ephemeral = true, api.nvim_buf_set_extmark(buf, ns, start_row, start_col, {
priority = priority, end_row = end_row,
conceal = conceal, end_col = end_col,
spell = spell, hl_group = hl,
url = url, ephemeral = true,
_subpriority = subtree_counter, priority = priority,
}) conceal = conceal,
spell = spell,
url = url,
_subpriority = subtree_counter,
})
end
end end
if if

View File

@@ -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); len = opts->ephemeral ? MAXCOL : ml_get_buf_len(buf, (linenr_T)line2 + 1);
} else if (line2 == buf->b_ml.ml_line_count) { } else if (line2 == buf->b_ml.ml_line_count) {
// We are trying to add an extmark past final newline // We are trying to add an extmark past final newline
// TODO(skewb1k): workaround for #35814. Investigate proper concurrency-safe handling of extmarks. len = 0;
len = opts->ephemeral ? MAXCOL : 0;
} else { } else {
// reuse len from before // reuse len from before
line2 = (int)line; line2 = (int)line;