diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-08-25 19:35:17 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-08-25 21:38:11 +0800 |
commit | 4ecea0e001533d68f3032fe0512fc55360f295c0 (patch) | |
tree | 1c1fdd54a6a2bdd7240e22cc455ab45b7db1160a | |
parent | 99f8d34c8a7128a9adb43168ca5364ccbd568333 (diff) | |
download | rneovim-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.c | 9 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 16 | ||||
-rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 27 | ||||
-rw-r--r-- | test/functional/legacy/cmdline_spec.lua | 79 |
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) |