aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-04-10 18:06:59 +0800
committerGitHub <noreply@github.com>2023-04-10 18:06:59 +0800
commit0e4086b74189c2b31ce63c6c5e85124edaf20d08 (patch)
tree302646fff83f5e464aafa72a6e995a06bb9c9959
parent5ed7ede1f58200e79bc1ac8a15356ef2fa7319b0 (diff)
downloadrneovim-0e4086b74189c2b31ce63c6c5e85124edaf20d08.tar.gz
rneovim-0e4086b74189c2b31ce63c6c5e85124edaf20d08.tar.bz2
rneovim-0e4086b74189c2b31ce63c6c5e85124edaf20d08.zip
fix(eval): prevent double-free in garbage collection (#22990)
-rw-r--r--src/nvim/eval/vars.c2
-rw-r--r--test/functional/vimscript/eval_spec.lua35
2 files changed, 36 insertions, 1 deletions
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c
index 701f190a06..9120cc4471 100644
--- a/src/nvim/eval/vars.c
+++ b/src/nvim/eval/vars.c
@@ -1149,7 +1149,7 @@ void vars_clear_ext(hashtab_T *ht, int free_val)
}
}
hash_clear(ht);
- ht->ht_used = 0;
+ hash_init(ht);
}
/// Delete a variable from hashtab "ht" at item "hi".
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua
index b995aaa5a6..b411b1e379 100644
--- a/test/functional/vimscript/eval_spec.lua
+++ b/test/functional/vimscript/eval_spec.lua
@@ -220,3 +220,38 @@ describe('listing functions using :function', function()
assert_alive()
end)
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', [[
+ func Foo() abort
+ let s:args = [a:000]
+ let foo0 = ""
+ let foo1 = ""
+ let foo2 = ""
+ let foo3 = ""
+ let foo4 = ""
+ let foo5 = ""
+ let foo6 = ""
+ let foo7 = ""
+ let foo8 = ""
+ let foo9 = ""
+ let foo10 = ""
+ let foo11 = ""
+ let foo12 = ""
+ let foo13 = ""
+ let foo14 = ""
+ endfunc
+
+ set updatetime=1
+ call Foo()
+ call Foo()
+ ]])
+ finally(function()
+ os.remove('Xgarbagecollect.vim')
+ end)
+ command('source Xgarbagecollect.vim')
+ sleep(10)
+ assert_alive()
+end)