summaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-09-17 16:27:39 +0100
committerBram Moolenaar <Bram@vim.org>2022-09-17 16:27:39 +0100
commitacd6b9976bd939035025a16ceb4213a680827927 (patch)
tree916b389f97f7a4094336ed69e9ab35d264718b0c /src/eval.c
parentd5bc762dea1fd32fa04342f8149f95ccfc3b9709 (diff)
patch 9.0.0487: using freed memory with combination of closuresv9.0.0487
Problem: Using freed memory with combination of closures. Solution: Do not use a partial after it has been freed through the funcstack.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index f280e2afc6..3209d08dcc 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4876,6 +4876,8 @@ partial_unref(partial_T *pt)
{
if (pt != NULL)
{
+ int done = FALSE;
+
if (--pt->pt_refcount <= 0)
partial_free(pt);
@@ -4883,9 +4885,12 @@ partial_unref(partial_T *pt)
// only reference and can be freed if no other partials reference it.
else if (pt->pt_refcount == 1)
{
+ // careful: if the funcstack is freed it may contain this partial
+ // and it gets freed as well
if (pt->pt_funcstack != NULL)
- funcstack_check_refcount(pt->pt_funcstack);
- if (pt->pt_loopvars != NULL)
+ done = funcstack_check_refcount(pt->pt_funcstack);
+
+ if (!done && pt->pt_loopvars != NULL)
loopvars_check_refcount(pt->pt_loopvars);
}
}