mirror of
https://github.com/neovim/neovim
synced 2025-07-27 08:52:10 +00:00
fix(pum): fix heap-buffer-overflow with 'rightleft' (#33146)
(cherry picked from commit 2681e1fce3
)
This commit is contained in:
committed by
github-actions[bot]
parent
06df3e0c0d
commit
c57a36cd59
@ -686,13 +686,13 @@ void pum_redraw(void)
|
|||||||
char *rt_start = rt;
|
char *rt_start = rt;
|
||||||
int cells = vim_strsize(rt);
|
int cells = vim_strsize(rt);
|
||||||
|
|
||||||
if (cells > pum_width) {
|
if (grid_col - cells < col_off - pum_width) {
|
||||||
do {
|
do {
|
||||||
cells -= utf_ptr2cells(rt);
|
cells -= utf_ptr2cells(rt);
|
||||||
MB_PTR_ADV(rt);
|
MB_PTR_ADV(rt);
|
||||||
} while (cells > pum_width);
|
} while (grid_col - cells < col_off - pum_width);
|
||||||
|
|
||||||
if (cells < pum_width) {
|
if (grid_col - cells > col_off - pum_width) {
|
||||||
// Most left character requires 2-cells but only 1 cell is available on
|
// Most left character requires 2-cells but only 1 cell is available on
|
||||||
// screen. Put a '<' on the left of the pum item.
|
// screen. Put a '<' on the left of the pum item.
|
||||||
*(--rt) = '<';
|
*(--rt) = '<';
|
||||||
|
@ -5498,7 +5498,8 @@ describe('builtin popupmenu', function()
|
|||||||
screen:try_resize(32, 8)
|
screen:try_resize(32, 8)
|
||||||
command('set completeopt+=menuone,noselect')
|
command('set completeopt+=menuone,noselect')
|
||||||
feed('i' .. string.rep(' ', 13))
|
feed('i' .. string.rep(' ', 13))
|
||||||
fn.complete(14, { '哦哦哦哦哦哦哦哦哦哦' })
|
|
||||||
|
fn.complete(14, { '一二三四五六七八九十' })
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect({
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
@ -5511,18 +5512,101 @@ describe('builtin popupmenu', function()
|
|||||||
## grid 3
|
## grid 3
|
||||||
{2:-- INSERT --} |
|
{2:-- INSERT --} |
|
||||||
## grid 4
|
## grid 4
|
||||||
{n: 哦哦哦哦哦哦哦哦哦>}|
|
{n: 一二三四五六七八九>}|
|
||||||
]],
|
]],
|
||||||
float_pos = { [4] = { -1, 'NW', 2, 1, 12, false, 100 } },
|
float_pos = { [4] = { -1, 'NW', 2, 1, 12, false, 100 } },
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
^ |
|
^ |
|
||||||
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}|
|
{1:~ }{n: 一二三四五六七八九>}|
|
||||||
{1:~ }|*5
|
{1:~ }|*5
|
||||||
{2:-- INSERT --} |
|
{2:-- INSERT --} |
|
||||||
]])
|
]])
|
||||||
end
|
end
|
||||||
|
feed('<C-E>')
|
||||||
|
|
||||||
|
fn.complete(14, { { word = '一二三', kind = '四五六', menu = '七八九十' } })
|
||||||
|
if multigrid then
|
||||||
|
screen:expect({
|
||||||
|
grid = [[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|*7
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1:~ }|*6
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{n: 一二三 四五六 七八>}|
|
||||||
|
]],
|
||||||
|
float_pos = { [4] = { -1, 'NW', 2, 1, 12, false, 100 } },
|
||||||
|
})
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }{n: 一二三 四五六 七八>}|
|
||||||
|
{1:~ }|*5
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
feed('<C-E>')
|
||||||
|
|
||||||
|
command('set rightleft')
|
||||||
|
fn.complete(14, { '一二三四五六七八九十' })
|
||||||
|
if multigrid then
|
||||||
|
screen:expect({
|
||||||
|
grid = [[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|*7
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1: ~}|*6
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{n:<九八七六五四三二一 }|
|
||||||
|
]],
|
||||||
|
float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } },
|
||||||
|
})
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{n:<九八七六五四三二一 }{1: ~}|
|
||||||
|
{1: ~}|*5
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
feed('<C-E>')
|
||||||
|
|
||||||
|
fn.complete(14, { { word = '一二三', kind = '四五六', menu = '七八九十' } })
|
||||||
|
if multigrid then
|
||||||
|
screen:expect({
|
||||||
|
grid = [[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|*7
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1: ~}|*6
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{n:<八七 六五四 三二一 }|
|
||||||
|
]],
|
||||||
|
float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } },
|
||||||
|
})
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{n:<八七 六五四 三二一 }{1: ~}|
|
||||||
|
{1: ~}|*5
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
feed('<C-E>')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('truncates double-width character correctly with scrollbar', function()
|
it('truncates double-width character correctly with scrollbar', function()
|
||||||
@ -5530,11 +5614,25 @@ describe('builtin popupmenu', function()
|
|||||||
command('set completeopt+=noselect')
|
command('set completeopt+=noselect')
|
||||||
command('set pumheight=4')
|
command('set pumheight=4')
|
||||||
feed('i' .. string.rep(' ', 12))
|
feed('i' .. string.rep(' ', 12))
|
||||||
local items = {}
|
local items1 = {}
|
||||||
|
local items2 = {}
|
||||||
for _ = 1, 8 do
|
for _ = 1, 8 do
|
||||||
table.insert(items, { word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1 })
|
table.insert(items1, { word = '一二三四五六七八九十', equal = 1, dup = 1 })
|
||||||
end
|
end
|
||||||
fn.complete(13, items)
|
for _ = 1, 2 do
|
||||||
|
table.insert(
|
||||||
|
items2,
|
||||||
|
{ word = 'abcdef', kind = 'ghijkl', menu = 'mnopqrst', equal = 1, dup = 1 }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
for _ = 3, 8 do
|
||||||
|
table.insert(
|
||||||
|
items2,
|
||||||
|
{ word = '一二三', kind = '四五六', menu = '七八九十', equal = 1, dup = 1 }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
fn.complete(13, items1)
|
||||||
if multigrid then
|
if multigrid then
|
||||||
screen:expect({
|
screen:expect({
|
||||||
grid = [[
|
grid = [[
|
||||||
@ -5547,20 +5645,109 @@ describe('builtin popupmenu', function()
|
|||||||
## grid 3
|
## grid 3
|
||||||
{2:-- INSERT --} |
|
{2:-- INSERT --} |
|
||||||
## grid 4
|
## grid 4
|
||||||
{n: 哦哦哦哦哦哦哦哦哦>}{c: }|*2
|
{n: 一二三四五六七八九>}{c: }|*2
|
||||||
{n: 哦哦哦哦哦哦哦哦哦>}{s: }|*2
|
{n: 一二三四五六七八九>}{s: }|*2
|
||||||
]],
|
]],
|
||||||
float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100 } },
|
float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100 } },
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
^ |
|
^ |
|
||||||
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }|*2
|
{1:~ }{n: 一二三四五六七八九>}{c: }|*2
|
||||||
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }|*2
|
{1:~ }{n: 一二三四五六七八九>}{s: }|*2
|
||||||
{1:~ }|*2
|
{1:~ }|*2
|
||||||
{2:-- INSERT --} |
|
{2:-- INSERT --} |
|
||||||
]])
|
]])
|
||||||
end
|
end
|
||||||
|
feed('<C-E>')
|
||||||
|
|
||||||
|
fn.complete(13, items2)
|
||||||
|
if multigrid then
|
||||||
|
screen:expect({
|
||||||
|
grid = [[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|*7
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1:~ }|*6
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{n: abcdef ghijkl mnopq}{c: }|*2
|
||||||
|
{n: 一二三 四五六 七八>}{s: }|*2
|
||||||
|
]],
|
||||||
|
float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100 } },
|
||||||
|
})
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }{n: abcdef ghijkl mnopq}{c: }|*2
|
||||||
|
{1:~ }{n: 一二三 四五六 七八>}{s: }|*2
|
||||||
|
{1:~ }|*2
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
feed('<C-E>')
|
||||||
|
|
||||||
|
command('set rightleft')
|
||||||
|
fn.complete(13, items1)
|
||||||
|
if multigrid then
|
||||||
|
screen:expect({
|
||||||
|
grid = [[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|*7
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1: ~}|*6
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{c: }{n:<九八七六五四三二一 }|*2
|
||||||
|
{s: }{n:<九八七六五四三二一 }|*2
|
||||||
|
]],
|
||||||
|
float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } },
|
||||||
|
})
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{c: }{n:<九八七六五四三二一 }{1: ~}|*2
|
||||||
|
{s: }{n:<九八七六五四三二一 }{1: ~}|*2
|
||||||
|
{1: ~}|*2
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
feed('<C-E>')
|
||||||
|
|
||||||
|
fn.complete(13, items2)
|
||||||
|
if multigrid then
|
||||||
|
screen:expect({
|
||||||
|
grid = [[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|*7
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1: ~}|*6
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{c: }{n:qponm lkjihg fedcba }|*2
|
||||||
|
{s: }{n:<八七 六五四 三二一 }|*2
|
||||||
|
]],
|
||||||
|
float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } },
|
||||||
|
})
|
||||||
|
else
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{c: }{n:qponm lkjihg fedcba }{1: ~}|*2
|
||||||
|
{s: }{n:<八七 六五四 三二一 }{1: ~}|*2
|
||||||
|
{1: ~}|*2
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
feed('<C-E>')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('supports mousemodel=popup', function()
|
it('supports mousemodel=popup', function()
|
||||||
|
Reference in New Issue
Block a user