mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
extmarks: fix crash due to invalid column values in inccommand preview
This used to use -1 and MAXCOL values. Make sure in range values are used.
This commit is contained in:
@@ -699,21 +699,30 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
|
||||
|
||||
// TODO(bfredl): if decoration had blocky mode, we could avoid this loop
|
||||
for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum ++) {
|
||||
int end_off = 0;
|
||||
if (pos_start.lnum < lnum && lnum < pos_end.lnum) {
|
||||
hl_start = offset-1;
|
||||
hl_end = MAXCOL;
|
||||
// TODO(bfredl): This is quite ad-hoc, but the space between |num| and
|
||||
// text being highlighted is the indication of \n being part of the
|
||||
// substituted text. But it would be more consistent to highlight
|
||||
// a space _after_ the previous line instead (like highlight EOL list
|
||||
// char)
|
||||
hl_start = MAX(offset-1, 0);
|
||||
end_off = 1;
|
||||
hl_end = 0;
|
||||
} else if (lnum == pos_start.lnum && lnum < pos_end.lnum) {
|
||||
hl_start = pos_start.col + offset;
|
||||
hl_end = MAXCOL;
|
||||
end_off = 1;
|
||||
hl_end = 0;
|
||||
} else if (pos_start.lnum < lnum && lnum == pos_end.lnum) {
|
||||
hl_start = offset-1;
|
||||
hl_start = MAX(offset-1, 0);
|
||||
hl_end = pos_end.col + offset;
|
||||
} else if (pos_start.lnum == lnum && pos_end.lnum == lnum) {
|
||||
hl_start = pos_start.col + offset;
|
||||
hl_end = pos_end.col + offset;
|
||||
}
|
||||
(void)extmark_add_decoration(buf, (uint64_t)src_id, hl_id,
|
||||
(int)lnum-1, hl_start, (int)lnum-1, hl_end,
|
||||
(int)lnum-1, hl_start,
|
||||
(int)lnum-1+end_off, hl_end,
|
||||
VIRTTEXT_EMPTY);
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ local wait = helpers.wait
|
||||
local nvim = helpers.nvim
|
||||
local sleep = helpers.sleep
|
||||
local nvim_dir = helpers.nvim_dir
|
||||
local assert_alive = helpers.assert_alive
|
||||
|
||||
local default_text = [[
|
||||
Inc substitution on
|
||||
@@ -84,6 +85,7 @@ local function common_setup(screen, inccommand, text)
|
||||
[14] = {foreground = Screen.colors.White, background = Screen.colors.Red},
|
||||
[15] = {bold=true, foreground=Screen.colors.Blue},
|
||||
[16] = {background=Screen.colors.Grey90}, -- cursorline
|
||||
[17] = {foreground = Screen.colors.Blue1},
|
||||
vis = {background=Screen.colors.LightGrey}
|
||||
})
|
||||
end
|
||||
@@ -2291,6 +2293,76 @@ describe(":substitute", function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it("inccommand=split, contraction of two subsequent NL chars", function()
|
||||
-- luacheck: push ignore 611
|
||||
local text = [[
|
||||
AAA AA
|
||||
|
||||
BBB BB
|
||||
|
||||
CCC CC
|
||||
|
||||
]]
|
||||
-- luacheck: pop
|
||||
|
||||
-- This used to crash, but more than 20 highlight entries are required
|
||||
-- to reproduce it (so that the marktree has multiple nodes)
|
||||
common_setup(screen, "split", string.rep(text,10))
|
||||
feed(":%s/\\n\\n/<c-v><c-m>/g")
|
||||
screen:expect{grid=[[
|
||||
CCC CC |
|
||||
AAA AA |
|
||||
BBB BB |
|
||||
CCC CC |
|
||||
|
|
||||
{11:[No Name] [+] }|
|
||||
| 1| AAA AA |
|
||||
| 2|{12: }BBB BB |
|
||||
| 3|{12: }CCC CC |
|
||||
| 4|{12: }AAA AA |
|
||||
| 5|{12: }BBB BB |
|
||||
| 6|{12: }CCC CC |
|
||||
| 7|{12: }AAA AA |
|
||||
{10:[Preview] }|
|
||||
:%s/\n\n/{17:^M}/g^ |
|
||||
]]}
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it("inccommand=nosplit, contraction of two subsequent NL chars", function()
|
||||
-- luacheck: push ignore 611
|
||||
local text = [[
|
||||
AAA AA
|
||||
|
||||
BBB BB
|
||||
|
||||
CCC CC
|
||||
|
||||
]]
|
||||
-- luacheck: pop
|
||||
|
||||
common_setup(screen, "nosplit", string.rep(text,10))
|
||||
feed(":%s/\\n\\n/<c-v><c-m>/g")
|
||||
screen:expect{grid=[[
|
||||
CCC CC |
|
||||
AAA AA |
|
||||
BBB BB |
|
||||
CCC CC |
|
||||
AAA AA |
|
||||
BBB BB |
|
||||
CCC CC |
|
||||
AAA AA |
|
||||
BBB BB |
|
||||
CCC CC |
|
||||
AAA AA |
|
||||
BBB BB |
|
||||
CCC CC |
|
||||
|
|
||||
:%s/\n\n/{17:^M}/g^ |
|
||||
]]}
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it("inccommand=split, multibyte text", function()
|
||||
common_setup(screen, "split", multibyte_text)
|
||||
feed(":%s/£.*ѫ/X¥¥")
|
||||
|
Reference in New Issue
Block a user