changeset 19914:6babfd2d15e9 v8.2.0513

patch 8.2.0513: reading past allocate memory when using varargs Commit: https://github.com/vim/vim/commit/5d905c2b9612314f6d8616560800665056050adc Author: Bram Moolenaar <Bram@vim.org> Date: Sun Apr 5 18:20:45 2020 +0200 patch 8.2.0513: reading past allocate memory when using varargs Problem: Reading past allocate memory when using varargs. Solution: Fix copying function argument types.
author Bram Moolenaar <Bram@vim.org>
date Sun, 05 Apr 2020 18:30:36 +0200
parents 9ab370ded046
children 882299cf6a38
files src/version.c src/vim9compile.c
diffstat 2 files changed, 16 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    513,
+/**/
     512,
 /**/
     511,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -353,7 +353,8 @@ get_func_type(type_T *ret_type, int argc
 }
 
 /*
- * For a function type, reserve space for "argcount" argument types.
+ * For a function type, reserve space for "argcount" argument types (including
+ * vararg).
  */
     static int
 func_type_add_arg_types(
@@ -5823,16 +5824,19 @@ compile_def_function(ufunc_T *ufunc, int
     }
 
     {
-	int argcount = ufunc->uf_args.ga_len
-					 + (ufunc->uf_va_name == NULL ? 0 : 1);
+	int varargs = ufunc->uf_va_name != NULL;
+	int argcount = ufunc->uf_args.ga_len - (varargs ? 1 : 0);
 
 	// Create a type for the function, with the return type and any
 	// argument types.
-	ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type, argcount,
-							 &ufunc->uf_type_list);
-	if (argcount > 0)
+	// A vararg is included in uf_args.ga_len but not in uf_arg_types.
+	// The type is included in "tt_args".
+	ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type,
+				  ufunc->uf_args.ga_len, &ufunc->uf_type_list);
+	if (ufunc->uf_args.ga_len > 0)
 	{
-	    if (func_type_add_arg_types(ufunc->uf_func_type, argcount,
+	    if (func_type_add_arg_types(ufunc->uf_func_type,
+			ufunc->uf_args.ga_len,
 			argcount - ufunc->uf_def_args.ga_len,
 						 &ufunc->uf_type_list) == FAIL)
 	    {
@@ -5850,6 +5854,9 @@ compile_def_function(ufunc_T *ufunc, int
 	    else
 		mch_memmove(ufunc->uf_func_type->tt_args,
 			     ufunc->uf_arg_types, sizeof(type_T *) * argcount);
+	    if (varargs)
+		ufunc->uf_func_type->tt_args[argcount] =
+			ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
 	}
     }