commit 612cd99a00174fc8c12a439781e7108a6efa8bea
parent a03ab03a10ada68b74e292a16493047da414e3ee
Author: Francisco Giordano <fg@frang.io>
Date: Fri, 2 Jan 2026 04:17:57 -0300
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`.
Diffstat:
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
@@ -270,8 +270,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 {
diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua
@@ -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()