changeset 5834:6bc874e4789a v7.4.260

updated for version 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.
author Bram Moolenaar <bram@vim.org>
date Wed, 23 Apr 2014 17:43:42 +0200
parents 31d944071cde
children 81784024a6ab
files src/eval.c src/testdir/test_eval.in src/testdir/test_eval.ok src/version.c
diffstat 4 files changed, 54 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -808,7 +808,7 @@ static int eval_fname_sid __ARGS((char_u
 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
 	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))
-    {
-	EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name);
+    else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len))
+    {
+	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.
- */
-    static int
-builtin_function(name)
+ * 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, len)
     char_u *name;
-{
-    return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL
-				   && vim_strchr(name, AUTOLOAD_CHAR) == NULL;
+    int len;
+{
+    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)
--- 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()
index 061e0cfd2f37ba12d5e66b1fe51221385b899374..a0d0e458ce28443b40c66fda650fcb9669a6a909
GIT binary patch
literal 10736
zc%02zOK;ma5awAxuQ?OmgA*WyZOPfTUijdLoCGL(>7th)2gy-V1BxBkO4}gV|Gs?9
zkd%gslk9Fbhe#UEeBY3o84hhfK0Xe3Sya3#cGWKGjCl2MSMVQy@E=)uUyOK`FZtm`
zS6sT6N5{PQb+@ev(de6N#7Hall-WDbc;_2>@@TxDn;r4kkz#ct4Ikxnr`c|`<h!EU
z7B^<zLLM8*VK?g@bBQ#O*Jbx8$|$;t;hXr5y5eX&j>htS>=WdMU@EUa1VK&_Obyc1
zCve3;Fs%_R4Z%!aOF^)t)_MkOI`bJkxulS{^6GJ18IHNUeiIy56vrH}=01lfHyrZ@
zM`1WpdCdh!VK@$kE=g*zQlG;W!%C$!hHJyHkk<pja7{8S4AjDBaK*r|s4?6ahEp|%
zL0@p(0LP&3lAIc}Q=h~Y1IZ~@e>JM_hU!dBMp1pIsm=`MnNQ`4f$EH;IyY43g5#Wu
z-g5(W?lZVzU^pM^yqw(K73-_j`iAeszp~)vYF+I3&sFsuc#nK9CXlI1NYx3Ms!9bC
zQ|tRlODbUcD#18FT|$mcsQA~mN{@N?+LZ93Mc3qsBWz@hU6FW?CDB}3onW+3K|lAh
z^%qh*t_MSfQNPbDSQ?cM6hdv_7fDh9%cT;8xYbSWavz*D$(5!@plt~^!m7SQN*Y{|
zc%LOv5KQY6j20{8=6<$>-;o{+E~;`rKk57H+HaqNwrq38U_UXPXW$T1<9qy#BkltE
zt1yG@7;D9h-j9`z-F?xjwmpZ{aJN>1Ms+}4td}z?mViNNHfa!pbn9s&SYq%}$!ng@
zp}WXo>z|X!IA=-;n+de4bsIq~aAs~^;XL;pNudQnM^e&}lqn@_Inc^)Ny1v#p%_Qf
zkRupGDHTM9LH)-V@h71{D8KfxG9i{m+D9dB1lj`HDh#v*6=(~lbg+v;BfrZEYhlwB
zDM_P|`11M5_JIYr?ihFB`UdEaz_uJWmSL(1%o0q=x{X*<RU&JptT~DWO3)G6&4Se>
zW>_)^CTbX}NgOq1HpiKjPHy_GzeSuAgw!w`1PH<uCPzoT1xpDoY8c{};9B71awl>R
zyv=HXZ)QOd5~CQZVvpoHPQMmaC8M-li8E+hpvn`ej<=+H*?K5VATX0!$a(|VkR`-^
zt;0<dmCkPME%-FSz^pOVM$9r#lg279forC@a_5}t*VY+0KdW*11Gul$XLSWkbEQTf
zRMG8ujifdLG1{DvJgr^~j(MyLlz2)m?UB{84OlEI8q>G~86R;MZMrV~9;(ufK@>}$
zqNY#R)+g!AHR((pz3u@u4zxh&R^2D#d1B*vi2+TYQxc}tZ1|d!MN&V*wQJgtkF+ct
z`K1p1tR?ofo)hS%kxa@)GPJ7N?9d{zV>1z+YqxTzz#shXrwP-FHYrTkmE`rjY1Ooe
zWO@-HZkB(O5^4veHvq*VG@Se~omUb!a;#O=CY=_M=U(&Ll|H?rLx|{$-NoHdfxG&i
z|6E(>3LxI}h3*kdXxLn!TLlaztxbg#+||#+&osp*0|QeJg`=~?{etd3Ama4Jo?hI@
zgS+~H=ef4fw<M8?T|GiJF(%q_+=Aw0ZrK3U>QtD*UH$O!OjA6OK=#Ra*VnwI(mvhl
zUg(}i#bFua``Ry67&CTH1U__5$kLibFGmff7mJKeAkmnO^Z0q`rk#~`?b+k_s!7@s
z@#UbQ6xAyrmB?geHfLgtdE8GvwB{@`&vAPKI=*U_)?|J$sIyBs+Y~ps&KZbeD(RU`
zxs$$Lhm*edDMP<4{k7N1xILX6w+&TWX?P8+Q#PLS*DNt+<rHr4obu)Ko(GoU`@WaG
z!}qbeXZj(r@}Ut44LO~REK35;6b%UkcL{4iU_p7Q18&*+?^vO%342q@q-6wVQNyND
z=4>N7T>4H(f%QT@CC<nYgvt?980n9iC9o-63KDM<Mu0(KdyP9@34H^4EVdHGR9Iyn
zp>af522Z@h(sxD*tTXZ{aYlw9gjW;(N>>7#lByu_Hem!9c2ckL$E)sd!4K`81kvwC
zn@4CH5r*U!+PdZrbKe^&u-?e0#2Fca5Z+Gid>MW)_~h*)653RG1&X%`Bj8{Yc#T8e
ze)9(OxGzZ*f8#M5jY1PofQ3>QiTJ2R5~jm^(D%L5BI}=iPQ1~f9l*DyzAwig82I0p
z8ydY{K;S$iEC3CkI{q_mdY@_jPh7(9Ei@j!Rshp4)<8KUJ`gk-*>?GzXX`69&tkV*
zZPvA4=k(y!_au3b+Ms%7iameDTrqgv8;8(Y7#_-&(s2pA0i<9xj<Mp9ze(zKg1=^>
z=AcdB2TeWrMH7k4TA)e)jTNFZ`-7=;yWMPeQTnS`-m6A%nU$sO{JyPj52fU2lnw@;
zM*PdB;>CJ%e<R-H_U8V!Sc|Uldb8!%_v>XP-ss5K1`r4T0;K)~^q3E8*dIsy&&`J4
zX6uKSAzz5v5qqE?lKzO_%b&3D&!S=G*^X!YYqb@Euy>Dt)i4HtF<&V+vhBluNMfEB
zm#=iF)9VP7&OrR{#2p{)<HtlUiAvPFtg4Fbx|Xn9KnR{<E0*<vuf?ldZq`+{TJ!4X
zhKr@W-E7T|dqVu<x8)y5c1bSXxRlrZS5&G&?8p#{MTjlTGhb)71;4!)Cc7%zR{98)
j3GTa9m6g)B&TiBh@tcwSU82dYSEEU+`0$8#evAGFtH*f}
--- 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,