diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-04-05 18:20:45 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-04-05 18:20:45 +0200 |
commit | 5d905c2b9612314f6d8616560800665056050adc (patch) | |
tree | df859a51e1191cfd10291b7c59dc62ca00357036 /src | |
parent | 5deeb3f1f9db4eabd36e99cbf857fe376eb37e10 (diff) | |
download | vim-git-5d905c2b9612314f6d8616560800665056050adc.tar.gz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 21 |
2 files changed, 16 insertions, 7 deletions
diff --git a/src/version.c b/src/version.c index 034c66be7..be99f998d 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 b040fd141..51014569e 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; } } |