summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-04-05 18:20:45 +0200
committerBram Moolenaar <Bram@vim.org>2020-04-05 18:20:45 +0200
commit5d905c2b9612314f6d8616560800665056050adc (patch)
treedf859a51e1191cfd10291b7c59dc62ca00357036
parent5deeb3f1f9db4eabd36e99cbf857fe376eb37e10 (diff)
patch 8.2.0513: reading past allocate memory when using varargsv8.2.0513
Problem: Reading past allocate memory when using varargs. Solution: Fix copying function argument types.
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c21
2 files changed, 16 insertions, 7 deletions
diff --git a/src/version.c b/src/version.c
index 034c66be76..be99f998dc 100644
--- 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,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index b040fd141a..51014569eb 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -353,7 +353,8 @@ get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
}
/*
- * 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 set_return_type)
}
{
- 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 set_return_type)
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;
}
}