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);
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1142,
+/**/
     1141,
 /**/
     1140,