diff options
author | Alexandre Teoi <ateoi@users.noreply.github.com> | 2023-07-26 00:22:57 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-26 11:22:57 +0800 |
commit | 643bea31b8673f5db70816ecac61f76087019fb5 (patch) | |
tree | c0153bf1be33b6b1aa5fbaf1043562a66d4dfdad /test/functional/ui/inccommand_user_spec.lua | |
parent | 74bd4aba57d2f1b224abe46a6de82911d14ef6c1 (diff) | |
download | rneovim-643bea31b8673f5db70816ecac61f76087019fb5.tar.gz rneovim-643bea31b8673f5db70816ecac61f76087019fb5.tar.bz2 rneovim-643bea31b8673f5db70816ecac61f76087019fb5.zip |
fix(inccommand): restrict cmdpreview undo calls (#24289)
Problem:
The cmdpreview saved undo nodes on cmdpreview_prepare() from ex_getln.c may
become invalid (free) if the preview function makes undo operations, causing
heap-use-after-free errors.
Solution:
Save the buffer undo list on cmdpreview_prepare)_ and start a new empty one. On
cmdpreview_restore_state(), undo all the entries in the new undo list and
restore the original one. With this approach, the preview function will be
allowed to undo only its own changes.
Fix #20036
Fix #20248
Diffstat (limited to 'test/functional/ui/inccommand_user_spec.lua')
-rw-r--r-- | test/functional/ui/inccommand_user_spec.lua | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/test/functional/ui/inccommand_user_spec.lua b/test/functional/ui/inccommand_user_spec.lua index 9cc6e095c5..8a1030fa25 100644 --- a/test/functional/ui/inccommand_user_spec.lua +++ b/test/functional/ui/inccommand_user_spec.lua @@ -435,6 +435,28 @@ describe("'inccommand' for user commands", function() ]]) assert_alive() end) + + it("no crash if preview callback executes undo", function() + command('set inccommand=nosplit') + exec_lua([[ + vim.api.nvim_create_user_command('Foo', function() end, { + nargs = '?', + preview = function(_, _, _) + vim.cmd.undo() + end, + }) + ]]) + + -- Clear undo history + command('set undolevels=-1') + feed('ggyyp') + command('set undolevels=1000') + + feed('yypp:Fo') + assert_alive() + feed('<Esc>:Fo') + assert_alive() + end) end) describe("'inccommand' with multiple buffers", function() |