To: vim_dev@googlegroups.com Subject: Patch 7.4.2134 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.2134 Problem: No error for using function() badly. Solution: Check for passing wrong function name. (Ken Takata) Files: src/eval.c, src/evalfunc.c, src/proto/userfunc.pro, src/testdir/test_expr.vim, src/userfunc.c, src/vim.h *** ../vim-7.4.2133/src/eval.c 2016-07-29 22:36:40.211701392 +0200 --- src/eval.c 2016-07-31 13:45:31.853111418 +0200 *************** *** 7813,7819 **** /* Don't allow hiding a function. When "v" is not NULL we might be * assigning another function to the same var, the type is checked * below. */ ! if (new_var && function_exists(name)) { EMSG2(_("E705: Variable name conflicts with existing function: %s"), name); --- 7813,7819 ---- /* Don't allow hiding a function. When "v" is not NULL we might be * assigning another function to the same var, the type is checked * below. */ ! if (new_var && function_exists(name, FALSE)) { EMSG2(_("E705: Variable name conflicts with existing function: %s"), name); *** ../vim-7.4.2133/src/evalfunc.c 2016-07-30 22:32:08.143330313 +0200 --- src/evalfunc.c 2016-07-31 13:45:31.853111418 +0200 *************** *** 2845,2851 **** } else if (*p == '*') /* internal or user defined function */ { ! n = function_exists(p + 1); } else if (*p == ':') { --- 2845,2851 ---- } else if (*p == '*') /* internal or user defined function */ { ! n = function_exists(p + 1, FALSE); } else if (*p == ':') { *************** *** 3577,3583 **** EMSG2(_(e_invarg2), s); /* Don't check an autoload name for existence here. */ else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL ! && !function_exists(s)) EMSG2(_("E700: Unknown function: %s"), s); else { --- 3577,3583 ---- EMSG2(_(e_invarg2), s); /* Don't check an autoload name for existence here. */ else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL ! && !function_exists(s, TRUE)) EMSG2(_("E700: Unknown function: %s"), s); else { *** ../vim-7.4.2133/src/proto/userfunc.pro 2016-07-29 22:36:40.211701392 +0200 --- src/proto/userfunc.pro 2016-07-31 13:45:31.853111418 +0200 *************** *** 9,15 **** void ex_function(exarg_T *eap); int eval_fname_script(char_u *p); int translated_function_exists(char_u *name); ! int function_exists(char_u *name); char_u *get_expanded_name(char_u *name, int check); void func_dump_profile(FILE *fd); void prof_child_enter(proftime_T *tm); --- 9,15 ---- void ex_function(exarg_T *eap); int eval_fname_script(char_u *p); int translated_function_exists(char_u *name); ! int function_exists(char_u *name, int no_deref); char_u *get_expanded_name(char_u *name, int check); void func_dump_profile(FILE *fd); void prof_child_enter(proftime_T *tm); *** ../vim-7.4.2133/src/testdir/test_expr.vim 2016-07-22 21:49:36.678031435 +0200 --- src/testdir/test_expr.vim 2016-07-31 13:45:31.853111418 +0200 *************** *** 172,174 **** --- 172,181 ---- call assert_fails("call substitute('xxx', '.', {m -> string(extend(m, ['x']))}, '')", 'E742:') call assert_fails("call substitute('xxx', '.', {m -> string(remove(m, 1))}, '')", 'E742:') endfunc + + func Test_function_with_funcref() + let s:f = function('type') + let s:fref = function(s:f) + call assert_equal(v:t_string, s:fref('x')) + call assert_fails("call function('s:f')", 'E700:') + endfunc *** ../vim-7.4.2133/src/userfunc.c 2016-07-29 22:36:40.207701429 +0200 --- src/userfunc.c 2016-07-31 13:45:31.857111381 +0200 *************** *** 295,301 **** if (ret == FAIL || **arg != '>') goto errret; ! /* Set up dictionaries for checking local variables and arguments. */ if (evaluate) eval_lavars_used = &eval_lavars; --- 295,301 ---- if (ret == FAIL || **arg != '>') goto errret; ! /* Set up a flag for checking local variables and arguments. */ if (evaluate) eval_lavars_used = &eval_lavars; *************** *** 1504,1509 **** --- 1504,1510 ---- * TFN_INT: internal function name OK * TFN_QUIET: be quiet * TFN_NO_AUTOLOAD: do not use script autoloading + * TFN_NO_DEREF: do not dereference a Funcref * Advances "pp" to just after the function name (if no error). */ static char_u * *************** *** 1618,1624 **** if (name == lv.ll_exp_name) name = NULL; } ! else { len = (int)(end - *pp); name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD); --- 1619,1625 ---- if (name == lv.ll_exp_name) name = NULL; } ! else if (!(flags & TFN_NO_DEREF)) { len = (int)(end - *pp); name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD); *************** *** 1690,1696 **** start); goto theend; } ! if (!skip && !(flags & TFN_QUIET)) { char_u *cp = vim_strchr(lv.ll_name, ':'); --- 1691,1697 ---- start); goto theend; } ! if (!skip && !(flags & TFN_QUIET) && !(flags & TFN_NO_DEREF)) { char_u *cp = vim_strchr(lv.ll_name, ':'); *************** *** 2381,2396 **** /* * Return TRUE if a function "name" exists. */ int ! function_exists(char_u *name) { char_u *nm = name; char_u *p; int n = FALSE; ! p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, ! NULL, NULL); nm = skipwhite(nm); /* Only accept "funcname", "funcname ", "funcname (..." and --- 2382,2401 ---- /* * Return TRUE if a function "name" exists. + * If "no_defef" is TRUE, do not dereference a Funcref. */ int ! function_exists(char_u *name, int no_deref) { char_u *nm = name; char_u *p; int n = FALSE; + int flag; ! flag = TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD; ! if (no_deref) ! flag |= TFN_NO_DEREF; ! p = trans_function_name(&nm, FALSE, flag, NULL, NULL); nm = skipwhite(nm); /* Only accept "funcname", "funcname ", "funcname (..." and *** ../vim-7.4.2133/src/vim.h 2016-07-30 14:12:19.475812375 +0200 --- src/vim.h 2016-07-31 13:45:31.857111381 +0200 *************** *** 2458,2463 **** --- 2458,2464 ---- #define TFN_INT 1 /* internal function name OK */ #define TFN_QUIET 2 /* no error messages */ #define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */ + #define TFN_NO_DEREF 8 /* do not dereference a Funcref */ /* Values for get_lval() flags argument: */ #define GLV_QUIET TFN_QUIET /* no error messages */ *** ../vim-7.4.2133/src/version.c 2016-07-30 23:18:44.648927772 +0200 --- src/version.c 2016-07-31 13:46:45.036444873 +0200 *************** *** 765,766 **** --- 765,768 ---- { /* Add new patch number below this line */ + /**/ + 2134, /**/ -- BEDEVERE: Stand by for attack!! [CUT TO enormous army forming up. Trebuchets, rows of PIKEMEN, siege towers, pennants flying, shouts of "Stand by for attack!" Traditional army build-up shots. The shouts echo across the ranks of the army. We see various groups reacting, and stirring themselves in readiness.] ARTHUR: Who are they? BEDEVERE: Oh, just some friends! "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///