mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:7.4.260
Problem: It is possible to define a function with a colon in the name. It is possible to define a function with a lower case character if a "#" appears after the name. Solution: Disallow using a colon other than with "s:". Ignore "#" after the name. https://code.google.com/p/vim/source/detail?r=6bc874e4789a0f912b4fd6b23afecf19d80b1605
This commit is contained in:
parent
a6e1738db3
commit
342764d70e
69
src/eval.c
69
src/eval.c
@ -835,7 +835,7 @@ static int eval_fname_sid(char_u *p);
|
|||||||
static void list_func_head(ufunc_T *fp, int indent);
|
static void list_func_head(ufunc_T *fp, int indent);
|
||||||
static ufunc_T *find_func(char_u *name);
|
static ufunc_T *find_func(char_u *name);
|
||||||
static int function_exists(char_u *name);
|
static int function_exists(char_u *name);
|
||||||
static int builtin_function(char_u *name);
|
static bool builtin_function(char_u *name, int len);
|
||||||
static void func_do_profile(ufunc_T *fp);
|
static void func_do_profile(ufunc_T *fp);
|
||||||
static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len,
|
static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len,
|
||||||
char *title,
|
char *title,
|
||||||
@ -7344,7 +7344,7 @@ call_func (
|
|||||||
rettv->vval.v_number = 0;
|
rettv->vval.v_number = 0;
|
||||||
error = ERROR_UNKNOWN;
|
error = ERROR_UNKNOWN;
|
||||||
|
|
||||||
if (!builtin_function(fname)) {
|
if (!builtin_function(fname, -1)) {
|
||||||
/*
|
/*
|
||||||
* User defined function.
|
* User defined function.
|
||||||
*/
|
*/
|
||||||
@ -17353,20 +17353,19 @@ void ex_function(exarg_T *eap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Get the function name. There are these situations:
|
||||||
* Get the function name. There are these situations:
|
// func function name
|
||||||
* func normal function name
|
// "name" == func, "fudi.fd_dict" == NULL
|
||||||
* "name" == func, "fudi.fd_dict" == NULL
|
// s:func script-local function name
|
||||||
* dict.func new dictionary entry
|
// dict.func new dictionary entry
|
||||||
* "name" == NULL, "fudi.fd_dict" set,
|
// "name" == NULL, "fudi.fd_dict" set,
|
||||||
* "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
|
// "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
|
||||||
* dict.func existing dict entry with a Funcref
|
// dict.func existing dict entry with a Funcref
|
||||||
* "name" == func, "fudi.fd_dict" set,
|
// "name" == func, "fudi.fd_dict" set,
|
||||||
* "fudi.fd_di" set, "fudi.fd_newkey" == NULL
|
// "fudi.fd_di" set, "fudi.fd_newkey" == NULL
|
||||||
* dict.func existing dict entry that's not a Funcref
|
// dict.func existing dict entry that's not a Funcref
|
||||||
* "name" == NULL, "fudi.fd_dict" set,
|
// "name" == NULL, "fudi.fd_dict" set,
|
||||||
* "fudi.fd_di" set, "fudi.fd_newkey" == NULL
|
// "fudi.fd_di" set, "fudi.fd_newkey" == NULL
|
||||||
*/
|
|
||||||
p = eap->arg;
|
p = eap->arg;
|
||||||
name = trans_function_name(&p, eap->skip, 0, &fudi);
|
name = trans_function_name(&p, eap->skip, 0, &fudi);
|
||||||
paren = (vim_strchr(p, '(') != NULL);
|
paren = (vim_strchr(p, '(') != NULL);
|
||||||
@ -17996,12 +17995,22 @@ trans_function_name (
|
|||||||
sprintf((char *)sid_buf, "%" PRId64 "_", (int64_t)current_SID);
|
sprintf((char *)sid_buf, "%" PRId64 "_", (int64_t)current_SID);
|
||||||
lead += (int)STRLEN(sid_buf);
|
lead += (int)STRLEN(sid_buf);
|
||||||
}
|
}
|
||||||
} else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) {
|
} else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len)) {
|
||||||
EMSG2(_(
|
EMSG2(_(
|
||||||
"E128: Function name must start with a capital or contain a colon: %s"),
|
"E128: Function name must start with a capital or \"s:\": %s"),
|
||||||
lv.ll_name);
|
lv.ll_name);
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!skip) {
|
||||||
|
char_u *cp = vim_strchr(lv.ll_name, ':');
|
||||||
|
|
||||||
|
if (cp != NULL && cp < end) {
|
||||||
|
EMSG2(_("E884: Function name cannot contain a colon: %s"), lv.ll_name);
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
name = alloc((unsigned)(len + lead + 1));
|
name = alloc((unsigned)(len + lead + 1));
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
if (lead > 0) {
|
if (lead > 0) {
|
||||||
@ -18012,7 +18021,7 @@ trans_function_name (
|
|||||||
STRCPY(name + 3, sid_buf);
|
STRCPY(name + 3, sid_buf);
|
||||||
}
|
}
|
||||||
memmove(name + lead, lv.ll_name, (size_t)len);
|
memmove(name + lead, lv.ll_name, (size_t)len);
|
||||||
name[len + lead] = NUL;
|
name[lead + len] = NUL;
|
||||||
}
|
}
|
||||||
*pp = end;
|
*pp = end;
|
||||||
|
|
||||||
@ -18117,8 +18126,9 @@ void free_all_functions(void)
|
|||||||
|
|
||||||
int translated_function_exists(char_u *name)
|
int translated_function_exists(char_u *name)
|
||||||
{
|
{
|
||||||
if (builtin_function(name))
|
if (builtin_function(name, -1)) {
|
||||||
return find_internal_func(name) >= 0;
|
return find_internal_func(name) >= 0;
|
||||||
|
}
|
||||||
return find_func(name) != NULL;
|
return find_func(name) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18158,14 +18168,19 @@ char_u *get_expanded_name(char_u *name, int check)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Return TRUE if "name" looks like a builtin function name: starts with a
|
||||||
* Return TRUE if "name" looks like a builtin function name: starts with a
|
/// lower case letter and doesn't contain AUTOLOAD_CHAR.
|
||||||
* lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR.
|
/// "len" is the length of "name", or -1 for NUL terminated.
|
||||||
*/
|
static bool builtin_function(char_u *name, int len)
|
||||||
static int builtin_function(char_u *name)
|
|
||||||
{
|
{
|
||||||
return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL
|
if (!ASCII_ISLOWER(name[0])) {
|
||||||
&& vim_strchr(name, AUTOLOAD_CHAR) == NULL;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char_u *p = vim_strchr(name, AUTOLOAD_CHAR);
|
||||||
|
|
||||||
|
return p == NULL
|
||||||
|
|| (len > 0 && p > name + len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
24
src/testdir/test_eval.in
Normal file
24
src/testdir/test_eval.in
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
STARTTEST
|
||||||
|
:" function name includes a colon
|
||||||
|
:try
|
||||||
|
: func! g:test()
|
||||||
|
: echo "test"
|
||||||
|
: endfunc
|
||||||
|
:catch
|
||||||
|
: let @a = v:exception
|
||||||
|
:endtry
|
||||||
|
:" function name folowed by #
|
||||||
|
:try
|
||||||
|
: func! test2() "#
|
||||||
|
: echo "test2"
|
||||||
|
: endfunc
|
||||||
|
:catch
|
||||||
|
: let @b = v:exception
|
||||||
|
:endtry
|
||||||
|
:%d
|
||||||
|
:pu a
|
||||||
|
:pu b
|
||||||
|
:1d
|
||||||
|
:wq! test.out
|
||||||
|
ENDTEST
|
||||||
|
start:
|
2
src/testdir/test_eval.ok
Normal file
2
src/testdir/test_eval.ok
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Vim(function):E128: Function name must start with a capital or "s:": g:test()
|
||||||
|
Vim(function):E128: Function name must start with a capital or "s:": test2() "#
|
@ -207,7 +207,7 @@ static int included_patches[] = {
|
|||||||
//263,
|
//263,
|
||||||
//262,
|
//262,
|
||||||
261,
|
261,
|
||||||
//260,
|
260,
|
||||||
//259,
|
//259,
|
||||||
//258,
|
//258,
|
||||||
//257,
|
//257,
|
||||||
|
Loading…
Reference in New Issue
Block a user