1
0
forked from aniani/vim

patch 9.0.0487: using freed memory with combination of closures

Problem:    Using freed memory with combination of closures.
Solution:   Do not use a partial after it has been freed through the
            funcstack.
This commit is contained in:
Bram Moolenaar
2022-09-17 16:27:39 +01:00
parent d5bc762dea
commit acd6b9976b
4 changed files with 31 additions and 19 deletions

View File

@@ -797,16 +797,19 @@ handle_closure_in_use(ectx_T *ectx, int free_arguments)
* funcstack may be the only reference to the partials in the local variables.
* Go over all of them, the funcref and can be freed if all partials
* referencing the funcstack have a reference count of one.
* Returns TRUE if the funcstack is freed, the partial referencing it will then
* also have been freed.
*/
void
int
funcstack_check_refcount(funcstack_T *funcstack)
{
int i;
garray_T *gap = &funcstack->fs_ga;
int done = 0;
int i;
garray_T *gap = &funcstack->fs_ga;
int done = 0;
typval_T *stack;
if (funcstack->fs_refcount > funcstack->fs_min_refcount)
return;
return FALSE;
for (i = funcstack->fs_var_offset; i < gap->ga_len; ++i)
{
typval_T *tv = ((typval_T *)gap->ga_data) + i;
@@ -816,18 +819,20 @@ funcstack_check_refcount(funcstack_T *funcstack)
&& tv->vval.v_partial->pt_refcount == 1)
++done;
}
if (done == funcstack->fs_min_refcount)
{
typval_T *stack = gap->ga_data;
if (done != funcstack->fs_min_refcount)
return FALSE;
// All partials referencing the funcstack have a reference count of
// one, thus the funcstack is no longer of use.
for (i = 0; i < gap->ga_len; ++i)
clear_tv(stack + i);
vim_free(stack);
remove_funcstack_from_list(funcstack);
vim_free(funcstack);
}
stack = gap->ga_data;
// All partials referencing the funcstack have a reference count of
// one, thus the funcstack is no longer of use.
for (i = 0; i < gap->ga_len; ++i)
clear_tv(stack + i);
vim_free(stack);
remove_funcstack_from_list(funcstack);
vim_free(funcstack);
return TRUE;
}
/*