tui: final_column_wrap(): fix row calculation

closes #7572
closes #7579
closes #7628

ASAN report:

    ==9500==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040000024c0 at pc 0x00000187d2ca bp 0x7fc3c6e58d10 sp 0x7fc3c6e58d08
    READ of size 8 at 0x6040000024c0 thread T1
        0 0x187d2c9 in ugrid_put /home/vagrant/neovim/build/../src/nvim/ugrid.c:107:17
        1 0x1850adf in tui_put /home/vagrant/neovim/build/../src/nvim/tui/tui.c:1012:10
        2 0x18a6ce6 in ui_bridge_put_event /home/vagrant/neovim/build/src/nvim/auto/ui_events_bridge.generated.h:154:3
        3 0xa4dcda in multiqueue_process_events /home/vagrant/neovim/build/../src/nvim/event/multiqueue.c:150:7
        4 0xa478bf in loop_poll_events /home/vagrant/neovim/build/../src/nvim/event/loop.c:63:3
        5 0x185451c in tui_main /home/vagrant/neovim/build/../src/nvim/tui/tui.c:362:12
        6 0x18a3080 in ui_thread_run /home/vagrant/neovim/build/../src/nvim/ui_bridge.c:106:3
        7 0x7fc3caaac6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
        8 0x7fc3c9ca33dc in clone /build/glibc-bfm8X4/glibc-2.23/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:109

    0x6040000024c0 is located 0 bytes to the right of 48-byte region [0x604000002490,0x6040000024c0)
    allocated by thread T1 here:
        0 0x50e048 in malloc (/home/vagrant/neovim/build/bin/nvim+0x50e048)
        1 0xf7ab71 in try_malloc /home/vagrant/neovim/build/../src/nvim/memory.c:87:15
        2 0xf7ad99 in xmalloc /home/vagrant/neovim/build/../src/nvim/memory.c:121:15
        3 0x187937b in ugrid_resize /home/vagrant/neovim/build/../src/nvim/ugrid.c:32:17
        4 0x184be58 in tui_resize /home/vagrant/neovim/build/../src/nvim/tui/tui.c:770:3
        5 0x18a3dc8 in ui_bridge_resize_event /home/vagrant/neovim/build/src/nvim/auto/ui_events_bridge.generated.h:4:3
        6 0xa4dcda in multiqueue_process_events /home/vagrant/neovim/build/../src/nvim/event/multiqueue.c:150:7
        7 0xa478bf in loop_poll_events /home/vagrant/neovim/build/../src/nvim/event/loop.c:63:3
        8 0x185451c in tui_main /home/vagrant/neovim/build/../src/nvim/tui/tui.c:362:12
        9 0x18a3080 in ui_thread_run /home/vagrant/neovim/build/../src/nvim/ui_bridge.c:106:3
        10 0x7fc3caaac6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)

    Thread T1 created by T0 here:
        0 0x4655ed in __interceptor_pthread_create (/home/vagrant/neovim/build/bin/nvim+0x4655ed)
        1 0x1ad87b0 in uv_thread_create /home/vagrant/neovim/.deps/build/src/libuv/src/unix/thread.c:75
        2 0x184b9aa in tui_start /home/vagrant/neovim/build/../src/nvim/tui/tui.c:159:10
        3 0x188dd4c in ui_builtin_start /home/vagrant/neovim/build/../src/nvim/ui.c:125:3
        4 0xe6d399 in main /home/vagrant/neovim/build/../src/nvim/main.c:457:5
        5 0x7fc3c9bbc82f in __libc_start_main /build/glibc-bfm8X4/glibc-2.23/csu/../csu/libc-start.c:291
This commit is contained in:
Justin M. Keyes
2018-01-16 09:08:31 +01:00
parent 60d6a8b13d
commit 1be315de37
2 changed files with 28 additions and 3 deletions

View File

@@ -500,7 +500,7 @@ static void final_column_wrap(UI *ui)
UGrid *grid = &data->grid; UGrid *grid = &data->grid;
if (grid->col == ui->width) { if (grid->col == ui->width) {
grid->col = 0; grid->col = 0;
if (grid->row < ui->height) { if (grid->row < MIN(ui->height, grid->height - 1)) {
grid->row++; grid->row++;
} }
} }

View File

@@ -6,15 +6,18 @@ local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers') local thelpers = require('test.functional.terminal.helpers')
local Screen = require('test.functional.ui.screen') local Screen = require('test.functional.ui.screen')
local eq = helpers.eq local eq = helpers.eq
local feed_data = thelpers.feed_data
local feed_command = helpers.feed_command local feed_command = helpers.feed_command
local feed_data = thelpers.feed_data
local clear = helpers.clear local clear = helpers.clear
local command = helpers.command
local eval = helpers.eval
local nvim_dir = helpers.nvim_dir local nvim_dir = helpers.nvim_dir
local retry = helpers.retry local retry = helpers.retry
local nvim_prog = helpers.nvim_prog local nvim_prog = helpers.nvim_prog
local nvim_set = helpers.nvim_set local nvim_set = helpers.nvim_set
local ok = helpers.ok local ok = helpers.ok
local read_file = helpers.read_file local read_file = helpers.read_file
local wait = helpers.wait
if helpers.pending_win32(pending) then return end if helpers.pending_win32(pending) then return end
@@ -40,6 +43,28 @@ describe('tui', function()
screen:detach() screen:detach()
end) end)
it('rapid resize #7572 #7628', function()
-- Need buffer rows to provoke the behavior.
feed_data(":edit test/functional/fixtures/bigfile.txt:")
command('call jobresize(b:terminal_job_id, 58, 9)')
command('call jobresize(b:terminal_job_id, 62, 13)')
command('call jobresize(b:terminal_job_id, 100, 42)')
command('call jobresize(b:terminal_job_id, 37, 1000)')
-- Resize to <5 columns.
screen:try_resize(4, 44)
command('call jobresize(b:terminal_job_id, 4, 1000)')
-- Resize to 1 row, then to 1 column, then increase rows to 4.
screen:try_resize(44, 1)
command('call jobresize(b:terminal_job_id, 44, 1)')
screen:try_resize(1, 1)
command('call jobresize(b:terminal_job_id, 1, 1)')
screen:try_resize(1, 4)
command('call jobresize(b:terminal_job_id, 1, 4)')
screen:try_resize(57, 17)
command('call jobresize(b:terminal_job_id, 57, 17)')
eq(2, eval("1+1")) -- Still alive?
end)
it('accepts basic utf-8 input', function() it('accepts basic utf-8 input', function()
feed_data('iabc\ntest1\ntest2') feed_data('iabc\ntest1\ntest2')
screen:expect([[ screen:expect([[
@@ -448,7 +473,7 @@ describe("tui 't_Co' (terminal colors)", function()
nvim_set)) nvim_set))
feed_data(":echo &t_Co\n") feed_data(":echo &t_Co\n")
helpers.wait() wait()
local tline local tline
if maxcolors == 8 or maxcolors == 16 then if maxcolors == 8 or maxcolors == 16 then
tline = "~ " tline = "~ "