Mercurial > vim
comparison src/vim9cmds.c @ 30166:d1c04b4dc60d v9.0.0419
patch 9.0.0419: the :defer command does not check the function arguments
Commit: https://github.com/vim/vim/commit/169003289fb4b2ad18fd7f5807e0d05efff0be85
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Sep 8 19:51:45 2022 +0100
patch 9.0.0419: the :defer command does not check the function arguments
Problem: The :defer command does not check the function argument count and
types.
Solution: Check the function arguments when adding a deferred function.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 08 Sep 2022 21:00:04 +0200 |
parents | 4eac06fb0191 |
children | 6472aa128651 |
comparison
equal
deleted
inserted
replaced
30165:27820ff1eaf4 | 30166:d1c04b4dc60d |
---|---|
1683 | 1683 |
1684 return skipwhite(p); | 1684 return skipwhite(p); |
1685 } | 1685 } |
1686 | 1686 |
1687 /* | 1687 /* |
1688 * Get the local variable index for deferred function calls. | |
1689 * Reserve it when not done already. | |
1690 * Returns zero for failure. | |
1691 */ | |
1692 int | |
1693 get_defer_var_idx(cctx_T *cctx) | |
1694 { | |
1695 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) | |
1696 + cctx->ctx_ufunc->uf_dfunc_idx; | |
1697 if (dfunc->df_defer_var_idx == 0) | |
1698 { | |
1699 lvar_T *lvar = reserve_local(cctx, (char_u *)"@defer@", 7, | |
1700 TRUE, &t_list_any); | |
1701 if (lvar == NULL) | |
1702 return 0; | |
1703 dfunc->df_defer_var_idx = lvar->lv_idx + 1; | |
1704 } | |
1705 return dfunc->df_defer_var_idx; | |
1706 } | |
1707 | |
1708 /* | |
1709 * Compile "defer func(arg)". | 1688 * Compile "defer func(arg)". |
1710 */ | 1689 */ |
1711 char_u * | 1690 char_u * |
1712 compile_defer(char_u *arg_start, cctx_T *cctx) | 1691 compile_defer(char_u *arg_start, cctx_T *cctx) |
1713 { | 1692 { |
1714 char_u *p; | 1693 char_u *paren; |
1715 char_u *arg = arg_start; | 1694 char_u *arg = arg_start; |
1716 int argcount = 0; | 1695 int argcount = 0; |
1717 int defer_var_idx; | 1696 int defer_var_idx; |
1718 type_T *type; | 1697 type_T *type; |
1719 int func_idx; | 1698 int func_idx; |
1720 | 1699 |
1721 // Get a funcref for the function name. | 1700 // Get a funcref for the function name. |
1722 // TODO: better way to find the "(". | 1701 // TODO: better way to find the "(". |
1723 p = vim_strchr(arg, '('); | 1702 paren = vim_strchr(arg, '('); |
1724 if (p == NULL) | 1703 if (paren == NULL) |
1725 { | 1704 { |
1726 semsg(_(e_missing_parenthesis_str), arg); | 1705 semsg(_(e_missing_parenthesis_str), arg); |
1727 return NULL; | 1706 return NULL; |
1728 } | 1707 } |
1729 *p = NUL; | 1708 *paren = NUL; |
1730 func_idx = find_internal_func(arg); | 1709 func_idx = find_internal_func(arg); |
1731 if (func_idx >= 0) | 1710 if (func_idx >= 0) |
1732 // TODO: better type | 1711 // TODO: better type |
1733 generate_PUSHFUNC(cctx, (char_u *)internal_func_name(func_idx), | 1712 generate_PUSHFUNC(cctx, (char_u *)internal_func_name(func_idx), |
1734 &t_func_any, FALSE); | 1713 &t_func_any, FALSE); |
1735 else if (compile_expr0(&arg, cctx) == FAIL) | 1714 else if (compile_expr0(&arg, cctx) == FAIL) |
1736 return NULL; | 1715 return NULL; |
1737 *p = '('; | 1716 *paren = '('; |
1738 | 1717 |
1739 // check for function type | 1718 // check for function type |
1740 type = get_type_on_stack(cctx, 0); | 1719 type = get_type_on_stack(cctx, 0); |
1741 if (type->tt_type != VAR_FUNC) | 1720 if (type->tt_type != VAR_FUNC) |
1742 { | 1721 { |
1743 emsg(_(e_function_name_required)); | 1722 emsg(_(e_function_name_required)); |
1744 return NULL; | 1723 return NULL; |
1745 } | 1724 } |
1746 | 1725 |
1747 // compile the arguments | 1726 // compile the arguments |
1748 arg = skipwhite(p + 1); | 1727 arg = skipwhite(paren + 1); |
1749 if (compile_arguments(&arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL) | 1728 if (compile_arguments(&arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL) |
1750 return NULL; | 1729 return NULL; |
1751 | 1730 |
1752 // TODO: check argument count with "type" | 1731 if (func_idx >= 0) |
1732 { | |
1733 type2_T *argtypes = NULL; | |
1734 type2_T shuffled_argtypes[MAX_FUNC_ARGS]; | |
1735 | |
1736 if (check_internal_func_args(cctx, func_idx, argcount, FALSE, | |
1737 &argtypes, shuffled_argtypes) == FAIL) | |
1738 return NULL; | |
1739 } | |
1740 else if (check_func_args_from_type(cctx, type, argcount, TRUE, | |
1741 arg_start) == FAIL) | |
1742 return NULL; | |
1753 | 1743 |
1754 defer_var_idx = get_defer_var_idx(cctx); | 1744 defer_var_idx = get_defer_var_idx(cctx); |
1755 if (defer_var_idx == 0) | 1745 if (defer_var_idx == 0) |
1756 return NULL; | 1746 return NULL; |
1757 if (generate_DEFER(cctx, defer_var_idx - 1, argcount) == FAIL) | 1747 if (generate_DEFER(cctx, defer_var_idx - 1, argcount) == FAIL) |