fix(api): buffer overflow in nvim_buf_get_extmarks overlap #37184

With `overlap=true`, more extmarks than the requested limit may be
collected in `extmark_get`. This then leads to an out of bounds write of
`rv` in `nvim_buf_get_extmarks`.

(cherry picked from commit 612cd99a00)
This commit is contained in:
Francisco Giordano
2026-01-02 04:17:57 -03:00
committed by github-actions[bot]
parent 44eae48b75
commit c124594b22
2 changed files with 14 additions and 2 deletions

View File

@@ -272,8 +272,11 @@ ExtmarkInfoArray extmark_get(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_co
return array;
}
MTPair pair;
while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) {
while ((int64_t)kv_size(array) < amount) {
MTPair pair;
if (!marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) {
break;
}
push_mark(&array, ns_id, type_filter, pair);
}
} else {

View File

@@ -817,6 +817,15 @@ describe('API/extmarks', function()
get_extmarks(ns, { 2, 0 }, { 2, -1 }, { overlap = true })
)
end)
it('limits overlap results', function()
set_extmark(ns, 1, 0, 0, { end_row = 5, end_col = 0 })
set_extmark(ns, 2, 2, 5, { end_row = 2, end_col = 30 })
set_extmark(ns, 3, 0, 5, { end_row = 2, end_col = 10 })
set_extmark(ns, 4, 0, 0, { end_row = 1, end_col = 0 })
local rv = get_extmarks(ns, { 2, 0 }, { 2, -1 }, { overlap = true, limit = 1 })
eq(1, #rv)
end)
end)
it('replace works', function()