]> granicus.if.org Git - vim/commitdiff
patch 8.2.2574: Vim9: crash when calling partial with wrong function v8.2.2574
authorBram Moolenaar <Bram@vim.org>
Sat, 6 Mar 2021 18:26:46 +0000 (19:26 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 6 Mar 2021 18:26:46 +0000 (19:26 +0100)
Problem:    Vim9: crash when calling partial with wrong function.
Solution:   Check argument types of called function. (closes #7912)

src/testdir/test_vim9_func.vim
src/version.c
src/vim9execute.c

index c7a968eb1e3fed99c9a7228cee044af456a4e9d1..2ac8609873dc453cc63387375cd965362dd6e7f2 100644 (file)
@@ -2367,6 +2367,30 @@ def Test_nested_lambda_in_closure()
   delete('XnestedDone')
 enddef
 
+def Test_check_func_arg_types()
+  var lines =<< trim END
+      vim9script
+      def F1(x: string): string
+        return x
+      enddef
+
+      def F2(x: number): number
+        return x + 1
+      enddef
+
+      def G(g: func): dict<func>
+        return {f: g}
+      enddef
+
+      def H(d: dict<func>): string
+        return d.f('a')
+      enddef
+  END
+
+  CheckScriptSuccess(lines + ['echo H(G(F1))'])
+  CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
+enddef
+
 
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 093f23d2d62466955a9ec2ddde18b5478fdfd574..278f77bc690007d4fc4c562e75fc93a6aed154f9 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2574,
 /**/
     2573,
 /**/
index e20c71105d53fd583aa1f7f691542ff3316c8afc..2e7e204e3c120be9686551760a4a298fbee05eea 100644 (file)
@@ -797,7 +797,27 @@ call_by_name(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr)
     }
 
     if (ufunc != NULL)
+    {
+       if (ufunc->uf_arg_types != NULL)
+       {
+           int i;
+           typval_T    *argv = STACK_TV_BOT(0) - argcount;
+
+           // The function can change at runtime, check that the argument
+           // types are correct.
+           for (i = 0; i < argcount; ++i)
+           {
+               type_T *type = i < ufunc->uf_args.ga_len
+                                 ? ufunc->uf_arg_types[i] : ufunc->uf_va_type;
+
+               if (type != NULL && check_typval_arg_type(type,
+                                                     &argv[i], i + 1) == FAIL)
+                   return FAIL;
+           }
+       }
+
        return call_ufunc(ufunc, NULL, argcount, ectx, iptr);
+    }
 
     return FAIL;
 }