diff options
author | Bram Moolenaar <Bram@vim.org> | 2014-04-23 17:43:42 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2014-04-23 17:43:42 +0200 |
commit | 9bdfb0025cba78c7a917f7f9420fe00136918e1c (patch) | |
tree | d054880923ec3a3ca5ed469807f8fde753880431 | |
parent | 62f167f716beb8bfeaadb8ec506a257827f701a2 (diff) |
updated for version 7.4.260v7.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.
-rw-r--r-- | src/eval.c | 40 | ||||
-rw-r--r-- | src/testdir/test_eval.in | 18 | ||||
-rw-r--r-- | src/testdir/test_eval.ok | bin | 10578 -> 10736 bytes | |||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 50 insertions, 10 deletions
diff --git a/src/eval.c b/src/eval.c index 275ef48117..2d29c92c04 100644 --- a/src/eval.c +++ b/src/eval.c @@ -808,7 +808,7 @@ static int eval_fname_sid __ARGS((char_u *p)); static void list_func_head __ARGS((ufunc_T *fp, int indent)); static ufunc_T *find_func __ARGS((char_u *name)); static int function_exists __ARGS((char_u *name)); -static int builtin_function __ARGS((char_u *name)); +static int builtin_function __ARGS((char_u *name, int len)); #ifdef FEAT_PROFILE static void func_do_profile __ARGS((ufunc_T *fp)); static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); @@ -8489,7 +8489,7 @@ call_func(funcname, len, rettv, argcount, argvars, firstline, lastline, rettv->vval.v_number = 0; error = ERROR_UNKNOWN; - if (!builtin_function(fname)) + if (!builtin_function(fname, -1)) { /* * User defined function. @@ -21584,6 +21584,7 @@ ex_function(eap) * Get the function name. There are these situations: * func normal function name * "name" == func, "fudi.fd_dict" == NULL + * s:func script-local function name * dict.func new dictionary entry * "name" == NULL, "fudi.fd_dict" set, * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func @@ -22314,11 +22315,24 @@ trans_function_name(pp, skip, flags, fdp) 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(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); + EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"), + lv.ll_name); 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)); if (name != NULL) { @@ -22331,7 +22345,7 @@ trans_function_name(pp, skip, flags, fdp) STRCPY(name + 3, sid_buf); } mch_memmove(name + lead, lv.ll_name, (size_t)len); - name[len + lead] = NUL; + name[lead + len] = NUL; } *pp = end; @@ -22452,7 +22466,7 @@ free_all_functions() translated_function_exists(name) char_u *name; { - if (builtin_function(name)) + if (builtin_function(name, -1)) return find_internal_func(name) >= 0; return find_func(name) != NULL; } @@ -22500,14 +22514,20 @@ get_expanded_name(name, check) /* * Return TRUE if "name" looks like a builtin function name: starts with a - * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. + * lower case letter and doesn't contain AUTOLOAD_CHAR. + * "len" is the length of "name", or -1 for NUL terminated. */ static int -builtin_function(name) +builtin_function(name, len) char_u *name; + int len; { - return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL - && vim_strchr(name, AUTOLOAD_CHAR) == NULL; + char_u *p; + + if (!ASCII_ISLOWER(name[0])) + return FALSE; + p = vim_strchr(name, AUTOLOAD_CHAR); + return p == NULL || (len > 0 && p > name + len); } #if defined(FEAT_PROFILE) || defined(PROTO) diff --git a/src/testdir/test_eval.in b/src/testdir/test_eval.in index b102be2b10..cb942011be 100644 --- a/src/testdir/test_eval.in +++ b/src/testdir/test_eval.in @@ -144,6 +144,24 @@ endfun :delcommand AR :call garbagecollect(1) :" +:" function name includes a colon +:try +:func! g:test() +:echo "test" +:endfunc +:catch +:$put =v:exception +:endtry +:" +:" function name folowed by # +:try +:func! test2() "# +:echo "test2" +:endfunc +:catch +:$put =v:exception +:endtry +:" :/^start:/+1,$wq! test.out :" vim: et ts=4 isk-=\: fmr=???,??? :call getchar() diff --git a/src/testdir/test_eval.ok b/src/testdir/test_eval.ok Binary files differindex 061e0cfd2f..a0d0e458ce 100644 --- a/src/testdir/test_eval.ok +++ b/src/testdir/test_eval.ok diff --git a/src/version.c b/src/version.c index f8464c0da9..1a112d7a48 100644 --- a/src/version.c +++ b/src/version.c @@ -735,6 +735,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 260, +/**/ 259, /**/ 258, |