changeset 32321:b9a8d1c453e1 v9.0.1492

patch 9.0.1492: using uninitialized memory when argument is missing Commit: https://github.com/vim/vim/commit/b7f2270bab102d68f83a6300699b7f98efad81f2 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Apr 27 16:24:07 2023 +0100 patch 9.0.1492: using uninitialized memory when argument is missing Problem: Using uninitialized memory when argument is missing. Solution: Check there are sufficient arguments before the base. (closes #12302)
author Bram Moolenaar <Bram@vim.org>
date Thu, 27 Apr 2023 17:30:05 +0200
parents 45c1a530fa76
children 8d73e57dd491
files src/evalfunc.c src/testdir/test_expr.vim src/testdir/test_listener.vim src/version.c src/vim9instr.c
diffstat 5 files changed, 23 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3134,6 +3134,9 @@ call_internal_method(
 
     if (global_functions[fi].f_argtype == FEARG_2)
     {
+	if (argcount < 1)
+	    return FCERR_TOOFEW;
+
 	// base value goes second
 	argv[0] = argvars[0];
 	argv[1] = *basetv;
@@ -3142,6 +3145,9 @@ call_internal_method(
     }
     else if (global_functions[fi].f_argtype == FEARG_3)
     {
+	if (argcount < 2)
+	    return FCERR_TOOFEW;
+
 	// base value goes third
 	argv[0] = argvars[0];
 	argv[1] = argvars[1];
@@ -3151,6 +3157,9 @@ call_internal_method(
     }
     else if (global_functions[fi].f_argtype == FEARG_4)
     {
+	if (argcount < 3)
+	    return FCERR_TOOFEW;
+
 	// base value goes fourth
 	argv[0] = argvars[0];
 	argv[1] = argvars[1];
--- a/src/testdir/test_expr.vim
+++ b/src/testdir/test_expr.vim
@@ -458,6 +458,9 @@ func Test_printf_misc()
   call v9.CheckLegacyAndVim9Success(lines)
 
   call v9.CheckLegacyAndVim9Failure(["call printf('123', 3)"], "E767:")
+
+  " this was using uninitialized memory
+  call v9.CheckLegacyAndVim9Failure(["eval ''->printf()"], "E119:")
 endfunc
 
 func Test_printf_float()
--- a/src/testdir/test_listener.vim
+++ b/src/testdir/test_listener.vim
@@ -212,6 +212,8 @@ func Test_listener_args()
   call assert_fails('call listener_add([])', 'E921:')
   call assert_fails('call listener_add("s:StoreListArgs", [])', 'E730:')
   call assert_fails('call listener_flush([])', 'E730:')
+
+  call assert_fails('eval ""->listener_add()', 'E119:')
 endfunc
 
 func s:StoreBufList(buf, start, end, added, list)
--- 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 */
 /**/
+    1492,
+/**/
     1491,
 /**/
     1490,
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -1626,8 +1626,14 @@ check_internal_func_args(
 
     if (method_call && argoff > 1)
     {
+	if (argcount < argoff)
+	{
+	    semsg(_(e_not_enough_arguments_for_function_str),
+						 internal_func_name(func_idx));
+	    return FAIL;
+	}
+
 	isn_T	*isn = generate_instr(cctx, ISN_SHUFFLE);
-
 	if (isn  == NULL)
 	    return FAIL;
 	isn->isn_arg.shuffle.shfl_item = argcount;