diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-03-06 19:26:46 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-03-06 19:26:46 +0100 |
commit | 04947cc6ed313b6b99889c27d008c68a373df634 (patch) | |
tree | e4400858556f9f43229f0c6e8aee07779e99107d | |
parent | a974953443775dd938cf9a8c195e3de9e4514f4f (diff) | |
download | vim-git-04947cc6ed313b6b99889c27d008c68a373df634.tar.gz |
patch 8.2.2574: Vim9: crash when calling partial with wrong functionv8.2.2574
Problem: Vim9: crash when calling partial with wrong function.
Solution: Check argument types of called function. (closes #7912)
-rw-r--r-- | src/testdir/test_vim9_func.vim | 24 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 20 |
3 files changed, 46 insertions, 0 deletions
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index c7a968eb1..2ac860987 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -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 diff --git a/src/version.c b/src/version.c index 093f23d2d..278f77bc6 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2574, +/**/ 2573, /**/ 2572, diff --git a/src/vim9execute.c b/src/vim9execute.c index e20c71105..2e7e204e3 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -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; } |