diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-07-31 23:47:12 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-07-31 23:47:12 +0200 |
commit | ce6583568ff5b3e0e6438b37ede2c80bedffba10 (patch) | |
tree | d9899ba05c65d4b330d64c71f43df13e4be9c103 /src/userfunc.c | |
parent | badd8486f7442bfcf55e0234ece80488958e7114 (diff) | |
download | vim-git-ce6583568ff5b3e0e6438b37ede2c80bedffba10.tar.gz |
patch 8.2.1332: Vim9: memory leak when using nested global functionv8.2.1332
Problem: Vim9: memory leak when using nested global function.
Solution: Delete the function when deleting the instruction. Disable test
that still causes a leak.
Diffstat (limited to 'src/userfunc.c')
-rw-r--r-- | src/userfunc.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/src/userfunc.c b/src/userfunc.c index de7034df8..cdce00560 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -780,7 +780,7 @@ find_func_with_sid(char_u *name, int sid) * When "is_global" is true don't find script-local or imported functions. * Return NULL for unknown function. */ - static ufunc_T * + ufunc_T * find_func_even_dead(char_u *name, int is_global, cctx_T *cctx) { hashitem_T *hi; @@ -1759,7 +1759,7 @@ delete_script_functions(int sid) { hashitem_T *hi; ufunc_T *fp; - long_u todo; + long_u todo = 1; char_u buf[30]; size_t len; @@ -1769,18 +1769,27 @@ delete_script_functions(int sid) sprintf((char *)buf + 3, "%d_", sid); len = STRLEN(buf); - todo = func_hashtab.ht_used; - for (hi = func_hashtab.ht_array; todo > 0; ++hi) - if (!HASHITEM_EMPTY(hi)) - { - fp = HI2UF(hi); - if (STRNCMP(fp->uf_name, buf, len) == 0) + while (todo > 0) + { + todo = func_hashtab.ht_used; + for (hi = func_hashtab.ht_array; todo > 0; ++hi) + if (!HASHITEM_EMPTY(hi)) { - fp->uf_flags |= FC_DEAD; - func_clear(fp, TRUE); + fp = HI2UF(hi); + if (STRNCMP(fp->uf_name, buf, len) == 0) + { + int changed = func_hashtab.ht_changed; + + fp->uf_flags |= FC_DEAD; + func_clear(fp, TRUE); + // When clearing a function another function can be cleared + // as a side effect. When that happens start over. + if (changed != func_hashtab.ht_changed) + break; + } + --todo; } - --todo; - } + } } #if defined(EXITFREE) || defined(PROTO) |