mirror of
https://github.com/vim/vim.git
synced 2025-07-04 23:07:33 -04:00
patch 7.4.2134
Problem: No error for using function() badly. Solution: Check for passing wrong function name. (Ken Takata)
This commit is contained in:
parent
fc1f2015e8
commit
b54c3ff317
@ -7813,7 +7813,7 @@ var_check_func_name(
|
||||
/* 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))
|
||||
if (new_var && function_exists(name, FALSE))
|
||||
{
|
||||
EMSG2(_("E705: Variable name conflicts with existing function: %s"),
|
||||
name);
|
||||
|
@ -2845,7 +2845,7 @@ f_exists(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
else if (*p == '*') /* internal or user defined function */
|
||||
{
|
||||
n = function_exists(p + 1);
|
||||
n = function_exists(p + 1, FALSE);
|
||||
}
|
||||
else if (*p == ':')
|
||||
{
|
||||
@ -3577,7 +3577,7 @@ f_function(typval_T *argvars, typval_T *rettv)
|
||||
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))
|
||||
&& !function_exists(s, TRUE))
|
||||
EMSG2(_("E700: Unknown function: %s"), s);
|
||||
else
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typva
|
||||
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 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);
|
||||
|
@ -172,3 +172,10 @@ func Test_substitute_expr_arg()
|
||||
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
|
||||
|
@ -295,7 +295,7 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
|
||||
if (ret == FAIL || **arg != '>')
|
||||
goto errret;
|
||||
|
||||
/* Set up dictionaries for checking local variables and arguments. */
|
||||
/* Set up a flag for checking local variables and arguments. */
|
||||
if (evaluate)
|
||||
eval_lavars_used = &eval_lavars;
|
||||
|
||||
@ -1504,6 +1504,7 @@ list_func_head(ufunc_T *fp, int indent)
|
||||
* 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,7 +1619,7 @@ trans_function_name(
|
||||
if (name == lv.ll_exp_name)
|
||||
name = NULL;
|
||||
}
|
||||
else
|
||||
else if (!(flags & TFN_NO_DEREF))
|
||||
{
|
||||
len = (int)(end - *pp);
|
||||
name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD);
|
||||
@ -1690,7 +1691,7 @@ trans_function_name(
|
||||
start);
|
||||
goto theend;
|
||||
}
|
||||
if (!skip && !(flags & TFN_QUIET))
|
||||
if (!skip && !(flags & TFN_QUIET) && !(flags & TFN_NO_DEREF))
|
||||
{
|
||||
char_u *cp = vim_strchr(lv.ll_name, ':');
|
||||
|
||||
@ -2381,16 +2382,20 @@ translated_function_exists(char_u *name)
|
||||
|
||||
/*
|
||||
* Return TRUE if a function "name" exists.
|
||||
* If "no_defef" is TRUE, do not dereference a Funcref.
|
||||
*/
|
||||
int
|
||||
function_exists(char_u *name)
|
||||
function_exists(char_u *name, int no_deref)
|
||||
{
|
||||
char_u *nm = name;
|
||||
char_u *p;
|
||||
int n = FALSE;
|
||||
int flag;
|
||||
|
||||
p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
|
||||
NULL, NULL);
|
||||
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
|
||||
|
@ -763,6 +763,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2134,
|
||||
/**/
|
||||
2133,
|
||||
/**/
|
||||
|
@ -2458,6 +2458,7 @@ int vim_main2(int argc, char **argv);
|
||||
#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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user