aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-08-25 19:35:17 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-08-25 21:38:11 +0800
commit4ecea0e001533d68f3032fe0512fc55360f295c0 (patch)
tree1c1fdd54a6a2bdd7240e22cc455ab45b7db1160a
parent99f8d34c8a7128a9adb43168ca5364ccbd568333 (diff)
downloadrneovim-4ecea0e001533d68f3032fe0512fc55360f295c0.tar.gz
rneovim-4ecea0e001533d68f3032fe0512fc55360f295c0.tar.bz2
rneovim-4ecea0e001533d68f3032fe0512fc55360f295c0.zip
vim-patch:8.2.0911: crash when opening a buffer for the cmdline window fails
Problem: Crash when opening a buffer for the cmdline window fails. (Chris Barber) Solution: Check do_ecmd() succeeds. Reset got_int if "q" was used at the more prompt. (closes vim/vim#6211) https://github.com/vim/vim/commit/9b7cce28d568f0622d77c6c9878c2d4770c3b164 Make code match latest Vim instead.
-rw-r--r--src/nvim/buffer.c9
-rw-r--r--src/nvim/ex_getln.c16
-rw-r--r--src/nvim/testdir/test_cmdline.vim27
-rw-r--r--test/functional/legacy/cmdline_spec.lua79
4 files changed, 126 insertions, 5 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index d0afaebad9..03b4c1bae8 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -4184,9 +4184,13 @@ void wipe_buffer(buf_T *buf, bool aucmd)
/// @param bufnr Buffer to switch to, or 0 to create a new buffer.
///
/// @see curbufIsChanged()
-void buf_open_scratch(handle_T bufnr, char *bufname)
+///
+/// @return FAIL for failure, OK otherwise
+int buf_open_scratch(handle_T bufnr, char *bufname)
{
- (void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
+ if (do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL) == FAIL) {
+ return FAIL;
+ }
apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf);
(void)setfname(curbuf, bufname, NULL, true);
apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf);
@@ -4194,4 +4198,5 @@ void buf_open_scratch(handle_T bufnr, char *bufname)
set_option_value_give_err("bt", 0L, "nofile", OPT_LOCAL);
set_option_value_give_err("swf", 0L, NULL, OPT_LOCAL);
RESET_BINDING(curwin);
+ return OK;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index afec21a86f..ce4930d33e 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -4073,17 +4073,27 @@ static int open_cmdwin(void)
ga_clear(&winsizes);
return K_IGNORE;
}
+ // Don't let quitting the More prompt make this fail.
+ got_int = false;
+
+ // Set "cmdwin_type" before any autocommands may mess things up.
cmdwin_type = get_cmdline_type();
cmdwin_level = ccline.level;
// Create empty command-line buffer.
- buf_open_scratch(0, _("[Command Line]"));
+ if (buf_open_scratch(0, _("[Command Line]")) == FAIL) {
+ // Some autocommand messed it up?
+ win_close(curwin, true, false);
+ ga_clear(&winsizes);
+ cmdwin_type = 0;
+ return Ctrl_C;
+ }
// Command-line buffer has bufhidden=wipe, unlike a true "scratch" buffer.
set_option_value_give_err("bh", 0L, "wipe", OPT_LOCAL);
- curwin->w_p_rl = cmdmsg_rl;
- cmdmsg_rl = false;
curbuf->b_p_ma = true;
curwin->w_p_fen = false;
+ curwin->w_p_rl = cmdmsg_rl;
+ cmdmsg_rl = false;
// Don't allow switching to another buffer.
curbuf->b_ro_locked++;
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index b7c6c1e4d1..e136bd7af0 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -1453,6 +1453,33 @@ func Test_cmdwin_tabpage()
tabclose!
endfunc
+func Test_cmdwin_interrupted()
+ CheckScreendump
+
+ " aborting the :smile output caused the cmdline window to use the current
+ " buffer.
+ let lines =<< trim [SCRIPT]
+ au WinNew * smile
+ [SCRIPT]
+ call writefile(lines, 'XTest_cmdwin')
+
+ let buf = RunVimInTerminal('-S XTest_cmdwin', {'rows': 18})
+ call TermWait(buf, 1000)
+ " open cmdwin
+ call term_sendkeys(buf, "q:")
+ call TermWait(buf, 500)
+ " quit more prompt for :smile command
+ call term_sendkeys(buf, "q")
+ call TermWait(buf, 500)
+ " execute a simple command
+ call term_sendkeys(buf, "aecho 'done'\<CR>")
+ call VerifyScreenDump(buf, 'Test_cmdwin_interrupted', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('XTest_cmdwin')
+endfunc
+
" Test for backtick expression in the command line
func Test_cmd_backtick()
CheckNotMSWindows " FIXME: see #19297
diff --git a/test/functional/legacy/cmdline_spec.lua b/test/functional/legacy/cmdline_spec.lua
index cf02636890..fb054eed9a 100644
--- a/test/functional/legacy/cmdline_spec.lua
+++ b/test/functional/legacy/cmdline_spec.lua
@@ -1,6 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
+local command = helpers.command
local feed = helpers.feed
local feed_command = helpers.feed_command
local exec = helpers.exec
@@ -141,3 +142,81 @@ describe('cmdline', function()
]])
end)
end)
+
+describe('cmdwin', function()
+ before_each(clear)
+
+ -- oldtest: Test_cmdwin_interrupted()
+ it('still uses a new buffer when interrupting more prompt on open', function()
+ local screen = Screen.new(30, 16)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {bold = true, reverse = true}, -- StatusLine
+ [2] = {reverse = true}, -- StatusLineNC
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg
+ [4] = {bold = true}, -- ModeMsg
+ })
+ screen:attach()
+ command('set more')
+ command('autocmd WinNew * highlight')
+ feed('q:')
+ screen:expect({any = '{3:%-%- More %-%-}^'})
+ feed('q')
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:[No Name] }|
+ {0::}^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[Command Line] }|
+ |
+ ]])
+ feed([[aecho 'done']])
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:[No Name] }|
+ {0::}echo 'done'^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[Command Line] }|
+ {4:-- INSERT --} |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ done |
+ ]])
+ end)
+end)