mirror of
https://github.com/neovim/neovim.git
synced 2025-09-23 11:38:31 +00:00
fix(swapfile): don't use uninitialized memory (#35813)
Also add a test for #35802.
This commit is contained in:
@@ -1403,8 +1403,8 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
|
|||||||
StringBuilder msg = KV_INITIAL_VALUE;
|
StringBuilder msg = KV_INITIAL_VALUE;
|
||||||
kv_resize(msg, IOSIZE);
|
kv_resize(msg, IOSIZE);
|
||||||
swapfile_info(files[i], &msg);
|
swapfile_info(files[i], &msg);
|
||||||
bool need_clear;
|
bool need_clear = false;
|
||||||
msg_multiline(cstr_as_string(msg.items), 0, false, false, &need_clear);
|
msg_multiline(cbuf_as_string(msg.items, msg.size), 0, false, false, &need_clear);
|
||||||
kv_destroy(msg);
|
kv_destroy(msg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -3569,8 +3569,8 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
|
|||||||
// pretend screen didn't scroll, need redraw anyway
|
// pretend screen didn't scroll, need redraw anyway
|
||||||
msg_reset_scroll();
|
msg_reset_scroll();
|
||||||
} else {
|
} else {
|
||||||
bool need_clear;
|
bool need_clear = false;
|
||||||
msg_multiline(cstr_as_string(msg.items), 0, false, false, &need_clear);
|
msg_multiline(cbuf_as_string(msg.items, msg.size), 0, false, false, &need_clear);
|
||||||
}
|
}
|
||||||
no_wait_return--;
|
no_wait_return--;
|
||||||
kv_destroy(msg);
|
kv_destroy(msg);
|
||||||
|
@@ -9,6 +9,7 @@ local clear = n.clear
|
|||||||
local command = n.command
|
local command = n.command
|
||||||
local feed = n.feed
|
local feed = n.feed
|
||||||
local fn = n.fn
|
local fn = n.fn
|
||||||
|
local neq = t.neq
|
||||||
local nvim_prog = n.nvim_prog
|
local nvim_prog = n.nvim_prog
|
||||||
local ok = t.ok
|
local ok = t.ok
|
||||||
local rmdir = n.rmdir
|
local rmdir = n.rmdir
|
||||||
@@ -51,7 +52,7 @@ describe("preserve and (R)ecover with custom 'directory'", function()
|
|||||||
set swapfile fileformat=unix undolevels=-1
|
set swapfile fileformat=unix undolevels=-1
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local nvim0
|
local nvim0 --- @type test.Session
|
||||||
before_each(function()
|
before_each(function()
|
||||||
nvim0 = n.new_session(false)
|
nvim0 = n.new_session(false)
|
||||||
set_session(nvim0)
|
set_session(nvim0)
|
||||||
@@ -63,12 +64,13 @@ describe("preserve and (R)ecover with custom 'directory'", function()
|
|||||||
rmdir(swapdir)
|
rmdir(swapdir)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
--- @return string
|
||||||
local function setup_swapname()
|
local function setup_swapname()
|
||||||
exec(init)
|
exec(init)
|
||||||
command('edit! ' .. testfile)
|
command('edit! ' .. testfile)
|
||||||
feed('isometext<esc>')
|
feed('isometext<esc>')
|
||||||
exec('redir => g:swapname | silent swapname | redir END')
|
exec('redir => g:swapname | silent swapname | redir END')
|
||||||
return eval('g:swapname')
|
return eval('g:swapname'):match('[^\n]*$')
|
||||||
end
|
end
|
||||||
|
|
||||||
local function test_recover(swappath1)
|
local function test_recover(swappath1)
|
||||||
@@ -99,6 +101,7 @@ describe("preserve and (R)ecover with custom 'directory'", function()
|
|||||||
it('with :preserve and SIGKILL', function()
|
it('with :preserve and SIGKILL', function()
|
||||||
local swappath1 = setup_swapname()
|
local swappath1 = setup_swapname()
|
||||||
command('preserve')
|
command('preserve')
|
||||||
|
neq(nil, uv.fs_stat(swappath1))
|
||||||
eq(0, vim.uv.kill(eval('getpid()'), 'sigkill'))
|
eq(0, vim.uv.kill(eval('getpid()'), 'sigkill'))
|
||||||
test_recover(swappath1)
|
test_recover(swappath1)
|
||||||
end)
|
end)
|
||||||
@@ -106,6 +109,7 @@ describe("preserve and (R)ecover with custom 'directory'", function()
|
|||||||
it('closing stdio channel without :preserve #22096', function()
|
it('closing stdio channel without :preserve #22096', function()
|
||||||
local swappath1 = setup_swapname()
|
local swappath1 = setup_swapname()
|
||||||
nvim0:close()
|
nvim0:close()
|
||||||
|
neq(nil, uv.fs_stat(swappath1))
|
||||||
test_recover(swappath1)
|
test_recover(swappath1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -124,13 +128,46 @@ describe("preserve and (R)ecover with custom 'directory'", function()
|
|||||||
set_session(nvim0)
|
set_session(nvim0)
|
||||||
command('call chanclose(&channel)') -- Kill the child process.
|
command('call chanclose(&channel)') -- Kill the child process.
|
||||||
screen0:expect({ any = pesc('[Process exited 1]') }) -- Wait for the child process to stop.
|
screen0:expect({ any = pesc('[Process exited 1]') }) -- Wait for the child process to stop.
|
||||||
|
neq(nil, uv.fs_stat(swappath1))
|
||||||
test_recover(swappath1)
|
test_recover(swappath1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('manual :recover with multiple swapfiles', function()
|
||||||
|
local swappath1 = setup_swapname()
|
||||||
|
eq('.swp', swappath1:match('%.[^.]+$'))
|
||||||
|
nvim0:close()
|
||||||
|
neq(nil, uv.fs_stat(swappath1))
|
||||||
|
local swappath2 = swappath1:gsub('%.swp$', '.swo')
|
||||||
|
eq(true, uv.fs_copyfile(swappath1, swappath2))
|
||||||
|
clear()
|
||||||
|
exec(init)
|
||||||
|
local screen = Screen.new(256, 40)
|
||||||
|
feed(':recover! ' .. testfile .. '<CR>')
|
||||||
|
screen:expect({
|
||||||
|
any = {
|
||||||
|
'\nSwap files found:',
|
||||||
|
'\n In directory ',
|
||||||
|
vim.pesc('\n1. '),
|
||||||
|
vim.pesc('\n2. '),
|
||||||
|
vim.pesc('\nEnter number of swap file to use (0 to quit): ^'),
|
||||||
|
},
|
||||||
|
none = vim.pesc('{18:^@}'),
|
||||||
|
})
|
||||||
|
feed('2<CR>')
|
||||||
|
screen:expect({
|
||||||
|
any = {
|
||||||
|
vim.pesc('\nRecovery completed.'),
|
||||||
|
vim.pesc('\n{6:Press ENTER or type command to continue}^'),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
feed('<CR>')
|
||||||
|
expect('sometext')
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('swapfile detection', function()
|
describe('swapfile detection', function()
|
||||||
local swapdir = uv.cwd() .. '/Xtest_swapdialog_dir'
|
local swapdir = uv.cwd() .. '/Xtest_swapdialog_dir'
|
||||||
local nvim0
|
local nvim0 --- @type test.Session
|
||||||
-- Put swapdir at the start of the 'directory' list. #1836
|
-- Put swapdir at the start of the 'directory' list. #1836
|
||||||
-- Note: `set swapfile` *must* go after `set directory`: otherwise it may
|
-- Note: `set swapfile` *must* go after `set directory`: otherwise it may
|
||||||
-- attempt to create a swapfile in different directory.
|
-- attempt to create a swapfile in different directory.
|
||||||
|
Reference in New Issue
Block a user