comparison src/vim9compile.c @ 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 d4fa9db88d16
children ccfeae6af59e
comparison
equal deleted inserted replaced
19913:9ab370ded046 19914:6babfd2d15e9
351 type->tt_args = NULL; 351 type->tt_args = NULL;
352 return type; 352 return type;
353 } 353 }
354 354
355 /* 355 /*
356 * For a function type, reserve space for "argcount" argument types. 356 * For a function type, reserve space for "argcount" argument types (including
357 * vararg).
357 */ 358 */
358 static int 359 static int
359 func_type_add_arg_types( 360 func_type_add_arg_types(
360 type_T *functype, 361 type_T *functype,
361 int argcount, 362 int argcount,
5821 dfunc->df_instr_count = instr->ga_len; 5822 dfunc->df_instr_count = instr->ga_len;
5822 dfunc->df_varcount = cctx.ctx_max_local; 5823 dfunc->df_varcount = cctx.ctx_max_local;
5823 } 5824 }
5824 5825
5825 { 5826 {
5826 int argcount = ufunc->uf_args.ga_len 5827 int varargs = ufunc->uf_va_name != NULL;
5827 + (ufunc->uf_va_name == NULL ? 0 : 1); 5828 int argcount = ufunc->uf_args.ga_len - (varargs ? 1 : 0);
5828 5829
5829 // Create a type for the function, with the return type and any 5830 // Create a type for the function, with the return type and any
5830 // argument types. 5831 // argument types.
5831 ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type, argcount, 5832 // A vararg is included in uf_args.ga_len but not in uf_arg_types.
5832 &ufunc->uf_type_list); 5833 // The type is included in "tt_args".
5833 if (argcount > 0) 5834 ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type,
5834 { 5835 ufunc->uf_args.ga_len, &ufunc->uf_type_list);
5835 if (func_type_add_arg_types(ufunc->uf_func_type, argcount, 5836 if (ufunc->uf_args.ga_len > 0)
5837 {
5838 if (func_type_add_arg_types(ufunc->uf_func_type,
5839 ufunc->uf_args.ga_len,
5836 argcount - ufunc->uf_def_args.ga_len, 5840 argcount - ufunc->uf_def_args.ga_len,
5837 &ufunc->uf_type_list) == FAIL) 5841 &ufunc->uf_type_list) == FAIL)
5838 { 5842 {
5839 ret = FAIL; 5843 ret = FAIL;
5840 goto erret; 5844 goto erret;
5848 ufunc->uf_func_type->tt_args[i] = &t_any; 5852 ufunc->uf_func_type->tt_args[i] = &t_any;
5849 } 5853 }
5850 else 5854 else
5851 mch_memmove(ufunc->uf_func_type->tt_args, 5855 mch_memmove(ufunc->uf_func_type->tt_args,
5852 ufunc->uf_arg_types, sizeof(type_T *) * argcount); 5856 ufunc->uf_arg_types, sizeof(type_T *) * argcount);
5857 if (varargs)
5858 ufunc->uf_func_type->tt_args[argcount] =
5859 ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
5853 } 5860 }
5854 } 5861 }
5855 5862
5856 ret = OK; 5863 ret = OK;
5857 5864