From 387c5ba3de356ea5c5f6fe71465440abd8563d8e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Dec 2023 09:55:11 +0800 Subject: revert: "memory: Free buffers after freeing variables" (#26356) This reverts commit fe30d8ccef17fff23676b8670dfec86444e2cb32. The original commit intends to prevent heap-use-after-free with EXITFREE caused by changedtick_di, which is no longer a problem. Freeing buffers after freeing variables will cause heap-use-after-free with EXITFREE when a partial is used as prompt callback. --- test/functional/vimscript/eval_spec.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'test/functional/vimscript/eval_spec.lua') diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index ab0ffccd4d..196e303738 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -15,6 +15,7 @@ local Screen = require('test.functional.ui.screen') local mkdir = helpers.mkdir local clear = helpers.clear local eq = helpers.eq +local exec = helpers.exec local exc_exec = helpers.exc_exec local exec_lua = helpers.exec_lua local exec_capture = helpers.exec_capture @@ -28,6 +29,7 @@ local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive local poke_eventloop = helpers.poke_eventloop local feed = helpers.feed +local expect_exit = helpers.expect_exit describe('Up to MAX_FUNC_ARGS arguments are handled by', function() local max_func_args = 20 -- from eval.h @@ -312,3 +314,14 @@ it('no double-free in garbage collection #16287', function() sleep(10) assert_alive() end) + +it('no heap-use-after-free with EXITFREE and partial as prompt callback', function() + clear() + exec([[ + func PromptCallback(text) + endfunc + setlocal buftype=prompt + call prompt_setcallback('', funcref('PromptCallback')) + ]]) + expect_exit(command, 'qall!') +end) -- cgit From 04f2f864e270e772c6326cefdf24947f0130e492 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 3 Jan 2024 02:09:18 +0100 Subject: refactor: format test/* --- test/functional/vimscript/eval_spec.lua | 103 ++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 39 deletions(-) (limited to 'test/functional/vimscript/eval_spec.lua') diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index 196e303738..a562f6f888 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -32,7 +32,7 @@ local feed = helpers.feed local expect_exit = helpers.expect_exit describe('Up to MAX_FUNC_ARGS arguments are handled by', function() - local max_func_args = 20 -- from eval.h + local max_func_args = 20 -- from eval.h local range = helpers.funcs.range before_each(clear) @@ -41,7 +41,7 @@ describe('Up to MAX_FUNC_ARGS arguments are handled by', function() local printf = helpers.funcs.printf local rep = helpers.funcs['repeat'] local expected = '2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,' - eq(expected, printf(rep('%d,', max_func_args-1), unpack(range(2, max_func_args)))) + eq(expected, printf(rep('%d,', max_func_args - 1), unpack(range(2, max_func_args)))) local ret = exc_exec('call printf("", 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)') eq('Vim(call):E740: Too many arguments for function printf', ret) end) @@ -55,15 +55,15 @@ describe('Up to MAX_FUNC_ARGS arguments are handled by', function() end) end) -describe("backtick expansion", function() +describe('backtick expansion', function() setup(function() clear() - mkdir("test-backticks") - write_file("test-backticks/file1", "test file 1") - write_file("test-backticks/file2", "test file 2") - write_file("test-backticks/file3", "test file 3") - mkdir("test-backticks/subdir") - write_file("test-backticks/subdir/file4", "test file 4") + mkdir('test-backticks') + write_file('test-backticks/file1', 'test file 1') + write_file('test-backticks/file2', 'test file 2') + write_file('test-backticks/file3', 'test file 3') + mkdir('test-backticks/subdir') + write_file('test-backticks/subdir/file4', 'test file 4') -- Long path might cause "Press ENTER" prompt; use :silent to avoid it. command('silent cd test-backticks') end) @@ -74,30 +74,30 @@ describe("backtick expansion", function() it("with default 'shell'", function() if helpers.is_os('win') then - command(":silent args `dir /b *2`") + command(':silent args `dir /b *2`') else - command(":silent args `echo ***2`") + command(':silent args `echo ***2`') end - eq({ "file2", }, eval("argv()")) + eq({ 'file2' }, eval('argv()')) if helpers.is_os('win') then - command(":silent args `dir /s/b *4`") - eq({ "subdir\\file4", }, eval("map(argv(), 'fnamemodify(v:val, \":.\")')")) + command(':silent args `dir /s/b *4`') + eq({ 'subdir\\file4' }, eval('map(argv(), \'fnamemodify(v:val, ":.")\')')) else - command(":silent args `echo */*4`") - eq({ "subdir/file4", }, eval("argv()")) + command(':silent args `echo */*4`') + eq({ 'subdir/file4' }, eval('argv()')) end end) - it("with shell=fish", function() + it('with shell=fish', function() if eval("executable('fish')") == 0 then pending('missing "fish" command') return end - command("set shell=fish") - command(":silent args `echo ***2`") - eq({ "file2", }, eval("argv()")) - command(":silent args `echo */*4`") - eq({ "subdir/file4", }, eval("argv()")) + command('set shell=fish') + command(':silent args `echo ***2`') + eq({ 'file2' }, eval('argv()')) + command(':silent args `echo */*4`') + eq({ 'subdir/file4' }, eval('argv()')) end) end) @@ -106,7 +106,9 @@ describe('List support code', function() local min_dur = 8 local len = 131072 - if not pending('does not actually allows interrupting with just got_int', function() end) then return end + if not pending('does not actually allows interrupting with just got_int', function() end) then + return + end -- The following tests are confirmed to work with os_breakcheck() just before -- `if (got_int) {break;}` in tv_list_copy and list_join_inner() and not to -- work without. @@ -153,7 +155,7 @@ describe('List support code', function() end) end) -describe("uncaught exception", function() +describe('uncaught exception', function() before_each(clear) it('is not forgotten #13490', function() @@ -164,11 +166,14 @@ describe("uncaught exception", function() -- from processing the others. -- Only the first thrown exception should be rethrown from the :try below, though. for i = 1, 3 do - write_file('throw' .. i .. '.vim', ([[ + write_file( + 'throw' .. i .. '.vim', + ([[ let result ..= '%d' throw 'throw%d' let result ..= 'X' - ]]):format(i, i)) + ]]):format(i, i) + ) end finally(function() for i = 1, 3 do @@ -184,9 +189,9 @@ describe("uncaught exception", function() it('multiline exception remains multiline #25350', function() local screen = Screen.new(80, 11) screen:set_default_attr_ids({ - [1] = {bold = true, reverse = true}; -- MsgSeparator - [2] = {foreground = Screen.colors.White, background = Screen.colors.Red}; -- ErrorMsg - [3] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg + [1] = { bold = true, reverse = true }, -- MsgSeparator + [2] = { foreground = Screen.colors.White, background = Screen.colors.Red }, -- ErrorMsg + [3] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) screen:attach() exec_lua([[ @@ -195,7 +200,8 @@ describe("uncaught exception", function() end ]]) feed(':try\rlua _G.Oops()\rendtry\r') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }| :try | : lua _G.Oops() | @@ -207,7 +213,8 @@ describe("uncaught exception", function() {2: [string ""]:2: in function 'Oops'} | {2: [string ":lua"]:1: in main chunk} | {3:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) end) @@ -217,16 +224,23 @@ describe('listing functions using :function', function() it('works for lambda functions with #20466', function() command('let A = {-> 1}') local num = exec_capture('echo A'):match("function%('(%d+)'%)") - eq(([[ + eq( + ([[ function %s(...) 1 return 1 - endfunction]]):format(num), exec_capture(('function %s'):format(num))) + endfunction]]):format(num), + exec_capture(('function %s'):format(num)) + ) end) it('does not crash if another function is deleted while listing', function() local screen = Screen.new(80, 24) screen:attach() - matches('Vim%(function%):E454: Function list was modified$', pcall_err(exec_lua, [=[ + matches( + 'Vim%(function%):E454: Function list was modified$', + pcall_err( + exec_lua, + [=[ vim.cmd([[ func Func1() endfunc @@ -247,14 +261,20 @@ describe('listing functions using :function', function() vim.cmd('function') vim.ui_detach(ns) - ]=])) + ]=] + ) + ) assert_alive() end) it('does not crash if the same function is deleted while listing', function() local screen = Screen.new(80, 24) screen:attach() - matches('Vim%(function%):E454: Function list was modified$', pcall_err(exec_lua, [=[ + matches( + 'Vim%(function%):E454: Function list was modified$', + pcall_err( + exec_lua, + [=[ vim.cmd([[ func Func1() endfunc @@ -275,7 +295,9 @@ describe('listing functions using :function', function() vim.cmd('function') vim.ui_detach(ns) - ]=])) + ]=] + ) + ) assert_alive() end) end) @@ -283,7 +305,9 @@ end) it('no double-free in garbage collection #16287', function() clear() -- Don't use exec() here as using a named script reproduces the issue better. - write_file('Xgarbagecollect.vim', [[ + write_file( + 'Xgarbagecollect.vim', + [[ func Foo() abort let s:args = [a:000] let foo0 = "" @@ -306,7 +330,8 @@ it('no double-free in garbage collection #16287', function() set updatetime=1 call Foo() call Foo() - ]]) + ]] + ) finally(function() os.remove('Xgarbagecollect.vim') end) -- cgit From 7a259d01aed52134a1675e47d9054ccad7ef7cbb Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 12 Jan 2024 11:41:09 +0000 Subject: test: remove helpers.sleep() --- test/functional/vimscript/eval_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/vimscript/eval_spec.lua') diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index a562f6f888..da8be7e90c 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -23,7 +23,7 @@ local eval = helpers.eval local command = helpers.command local write_file = helpers.write_file local meths = helpers.meths -local sleep = helpers.sleep +local sleep = vim.uv.sleep local matches = helpers.matches local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive -- cgit From c30f2e3182e3b50e7c03932027ac55edfc8ada4a Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 12 Jan 2024 12:44:54 +0000 Subject: test: typing for helpers.meths --- test/functional/vimscript/eval_spec.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test/functional/vimscript/eval_spec.lua') diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index da8be7e90c..180e6118fd 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -121,7 +121,7 @@ describe('List support code', function() let bl = range(%u) let dur = reltimestr(reltime(rt)) ]]):format(len)) - dur = tonumber(meths.get_var('dur')) + dur = tonumber(meths.nvim_get_var('dur')) if dur >= min_dur then -- print(('Using len %u, dur %g'):format(len, dur)) break @@ -136,7 +136,7 @@ describe('List support code', function() feed('') poke_eventloop() command('let t_dur = reltimestr(reltime(t_rt))') - local t_dur = tonumber(meths.get_var('t_dur')) + local t_dur = tonumber(meths.nvim_get_var('t_dur')) if t_dur >= dur / 8 then eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8)) end @@ -147,7 +147,7 @@ describe('List support code', function() feed('') poke_eventloop() command('let t_dur = reltimestr(reltime(t_rt))') - local t_dur = tonumber(meths.get_var('t_dur')) + local t_dur = tonumber(meths.nvim_get_var('t_dur')) print(('t_dur: %g'):format(t_dur)) if t_dur >= dur / 8 then eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8)) -- cgit From 795f896a5772d5e0795f86642bdf90c82efac45c Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 12 Jan 2024 17:59:57 +0000 Subject: test: rename (meths, funcs) -> (api, fn) --- test/functional/vimscript/eval_spec.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'test/functional/vimscript/eval_spec.lua') diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index 180e6118fd..e337959810 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -22,7 +22,7 @@ local exec_capture = helpers.exec_capture local eval = helpers.eval local command = helpers.command local write_file = helpers.write_file -local meths = helpers.meths +local api = helpers.api local sleep = vim.uv.sleep local matches = helpers.matches local pcall_err = helpers.pcall_err @@ -33,13 +33,13 @@ local expect_exit = helpers.expect_exit describe('Up to MAX_FUNC_ARGS arguments are handled by', function() local max_func_args = 20 -- from eval.h - local range = helpers.funcs.range + local range = helpers.fn.range before_each(clear) it('printf()', function() - local printf = helpers.funcs.printf - local rep = helpers.funcs['repeat'] + local printf = helpers.fn.printf + local rep = helpers.fn['repeat'] local expected = '2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,' eq(expected, printf(rep('%d,', max_func_args - 1), unpack(range(2, max_func_args)))) local ret = exc_exec('call printf("", 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)') @@ -47,7 +47,7 @@ describe('Up to MAX_FUNC_ARGS arguments are handled by', function() end) it('rpcnotify()', function() - local rpcnotify = helpers.funcs.rpcnotify + local rpcnotify = helpers.fn.rpcnotify local ret = rpcnotify(0, 'foo', unpack(range(3, max_func_args))) eq(1, ret) ret = exc_exec('call rpcnotify(0, "foo", 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)') @@ -121,7 +121,7 @@ describe('List support code', function() let bl = range(%u) let dur = reltimestr(reltime(rt)) ]]):format(len)) - dur = tonumber(meths.nvim_get_var('dur')) + dur = tonumber(api.nvim_get_var('dur')) if dur >= min_dur then -- print(('Using len %u, dur %g'):format(len, dur)) break @@ -136,7 +136,7 @@ describe('List support code', function() feed('') poke_eventloop() command('let t_dur = reltimestr(reltime(t_rt))') - local t_dur = tonumber(meths.nvim_get_var('t_dur')) + local t_dur = tonumber(api.nvim_get_var('t_dur')) if t_dur >= dur / 8 then eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8)) end @@ -147,7 +147,7 @@ describe('List support code', function() feed('') poke_eventloop() command('let t_dur = reltimestr(reltime(t_rt))') - local t_dur = tonumber(meths.nvim_get_var('t_dur')) + local t_dur = tonumber(api.nvim_get_var('t_dur')) print(('t_dur: %g'):format(t_dur)) if t_dur >= dur / 8 then eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8)) -- cgit