From 487c48ec8689b865bad04fdb87b61f5ada25da97 Mon Sep 17 00:00:00 2001 From: Artem Date: Wed, 25 Dec 2024 14:12:40 -0600 Subject: fix(api): clamp range lines in `nvim__redraw()` (#31710) Problem: `nvim__redraw()` doesn't clamp the lines in the `range` parameter before truncating to int. The resulting range may be empty when the original range contained buffer lines and vice versa. E.g. for a buffer with 4 lines, these are the redrawn lines: ```lua { 2, 2 ^ 31 } -> none (should be { 2, 3 }) { 2, 2 ^ 32 } -> none (should be { 2, 3 }) { 2 ^ 32 - 1, 2 } -> { 0, 1 } (should be none) ``` Solution: Clamp `range` values before truncating to int. --- src/nvim/api/vim.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 332c5bc15c..25f44bb4eb 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2374,13 +2374,23 @@ void nvim__redraw(Dict(redraw) *opts, Error *err) "%s", "Invalid 'range': Expected 2-tuple of Integers", { return; }); - linenr_T first = (linenr_T)kv_A(opts->range, 0).data.integer + 1; - linenr_T last = (linenr_T)kv_A(opts->range, 1).data.integer; + int64_t begin_raw = kv_A(opts->range, 0).data.integer; + int64_t end_raw = kv_A(opts->range, 1).data.integer; + buf_T *rbuf = win ? win->w_buffer : (buf ? buf : curbuf); - if (last == -1) { - last = rbuf->b_ml.ml_line_count; + linenr_T line_count = rbuf->b_ml.ml_line_count; + + int begin = (int)MIN(begin_raw, line_count); + int end; + if (end_raw == -1) { + end = line_count; + } else { + end = (int)MIN(MAX(begin, end_raw), line_count); + } + + if (begin < end) { + redraw_buf_range_later(rbuf, 1 + begin, end); } - redraw_buf_range_later(rbuf, first, last); } // Redraw later types require update_screen() so call implicitly unless set to false. -- cgit