Mercurial > vim
changeset 31620:2266b5c4f87b v9.0.1142
patch 9.0.1142: crash and/or memory leak when redefining function
Commit: https://github.com/vim/vim/commit/f057171d8b562c72334fd7c15c89ff787358ce3a
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Jan 4 13:16:20 2023 +0000
patch 9.0.1142: crash and/or memory leak when redefining function
Problem: Crash and/or memory leak when redefining function after error.
Solution: Clear pointer after making a copy. Clear arrays on failure.
(closes #11774)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 04 Jan 2023 14:30:03 +0100 |
parents | 50a4ca392ab6 |
children | 039dcfd1ee94 |
files | src/userfunc.c src/version.c |
diffstat | 2 files changed, 13 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -525,9 +525,9 @@ parse_argument_types(ufunc_T *fp, garray // Move the last argument "...name: type" to uf_va_name and // uf_va_type. - fp->uf_va_name = ((char_u **)fp->uf_args.ga_data) - [fp->uf_args.ga_len - 1]; --fp->uf_args.ga_len; + fp->uf_va_name = ((char_u **)fp->uf_args.ga_data)[fp->uf_args.ga_len]; + ((char_u **)fp->uf_args.ga_data)[fp->uf_args.ga_len] = NULL; p = ((char_u **)argtypes->ga_data)[len]; if (p == NULL) // TODO: get type from default value @@ -4787,7 +4787,7 @@ define_function( // invalid. ++p; if (get_function_args(&p, ')', &newargs, - eap->cmdidx == CMD_def ? &argtypes : NULL, FALSE, + eap->cmdidx == CMD_def ? &argtypes : NULL, FALSE, NULL, &varargs, &default_args, eap->skip, eap, in_class, &newlines, lines_to_free) == FAIL) goto errret_2; @@ -5209,17 +5209,23 @@ define_function( goto ret_free; erret: - ga_clear_strings(&newargs); - ga_clear_strings(&default_args); if (fp != NULL) { + // these were set to "newargs" and "default_args", which are cleared + // below ga_init(&fp->uf_args); ga_init(&fp->uf_def_args); } errret_2: + ga_clear_strings(&newargs); + ga_clear_strings(&default_args); ga_clear_strings(&newlines); if (fp != NULL) + { VIM_CLEAR(fp->uf_arg_types); + VIM_CLEAR(fp->uf_va_name); + clear_type_list(&fp->uf_type_list); + } if (free_fp) { vim_free(fp);