@@ -790,6 +790,8 @@ static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_
790790static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
791791static int var_check_ro __ARGS((int flags, char_u *name));
792792static int var_check_fixed __ARGS((int flags, char_u *name));
793+ static int var_check_func_name __ARGS((char_u *name, int new_var));
794+ static int valid_varname __ARGS((char_u *varname));
793795static int tv_check_lock __ARGS((int lock, char_u *name));
794796static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID));
795797static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
@@ -2717,8 +2719,27 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
27172719 lp->ll_list = NULL;
27182720 lp->ll_dict = lp->ll_tv->vval.v_dict;
27192721 lp->ll_di = dict_find(lp->ll_dict, key, len);
2722+
2723+ /* When assigning to g: check that a function and variable name is
2724+ * valid. */
2725+ if (rettv != NULL && lp->ll_dict == &globvardict)
2726+ {
2727+ if (rettv->v_type == VAR_FUNC
2728+ && var_check_func_name(key, lp->ll_di == NULL))
2729+ return NULL;
2730+ if (!valid_varname(key))
2731+ return NULL;
2732+ }
2733+
27202734 if (lp->ll_di == NULL)
27212735 {
2736+ /* Can't add "v:" variable. */
2737+ if (lp->ll_dict == &vimvardict)
2738+ {
2739+ EMSG2(_(e_illvar), name);
2740+ return NULL;
2741+ }
2742+
27222743 /* Key does not exist in dict: may need to add it. */
27232744 if (*p == '[' || *p == '.' || unlet)
27242745 {
@@ -2738,6 +2759,10 @@ get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
27382759 p = NULL;
27392760 break;
27402761 }
2762+ /* existing variable, need to check if it can be changed */
2763+ else if (var_check_ro(lp->ll_di->di_flags, name))
2764+ return NULL;
2765+
27412766 if (len == -1)
27422767 clear_tv(&var1);
27432768 lp->ll_tv = &lp->ll_di->di_tv;
@@ -19817,7 +19842,6 @@ set_var(name, tv, copy)
1981719842 dictitem_T *v;
1981819843 char_u *varname;
1981919844 hashtab_T *ht;
19820- char_u *p;
1982119845
1982219846 ht = find_var_ht(name, &varname);
1982319847 if (ht == NULL || *varname == NUL)
@@ -19827,25 +19851,8 @@ set_var(name, tv, copy)
1982719851 }
1982819852 v = find_var_in_ht(ht, varname, TRUE);
1982919853
19830- if (tv->v_type == VAR_FUNC)
19831- {
19832- if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
19833- && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
19834- ? name[2] : name[0]))
19835- {
19836- EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name);
19837- return;
19838- }
19839- /* Don't allow hiding a function. When "v" is not NULL we might be
19840- * assigning another function to the same var, the type is checked
19841- * below. */
19842- if (v == NULL && function_exists(name))
19843- {
19844- EMSG2(_("E705: Variable name conflicts with existing function: %s"),
19845- name);
19846- return;
19847- }
19848- }
19854+ if (tv->v_type == VAR_FUNC && var_check_func_name(name, v == NULL))
19855+ return;
1984919856
1985019857 if (v != NULL)
1985119858 {
@@ -19911,13 +19918,8 @@ set_var(name, tv, copy)
1991119918 }
1991219919
1991319920 /* Make sure the variable name is valid. */
19914- for (p = varname; *p != NUL; ++p)
19915- if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
19916- && *p != AUTOLOAD_CHAR)
19917- {
19918- EMSG2(_(e_illvar), varname);
19919- return;
19920- }
19921+ if (!valid_varname(varname))
19922+ return;
1992119923
1992219924 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
1992319925 + STRLEN(varname)));
@@ -19981,6 +19983,55 @@ var_check_fixed(flags, name)
1998119983 return FALSE;
1998219984}
1998319985
19986+ /*
19987+ * Check if a funcref is assigned to a valid variable name.
19988+ * Return TRUE and give an error if not.
19989+ */
19990+ static int
19991+ var_check_func_name(name, new_var)
19992+ char_u *name; /* points to start of variable name */
19993+ int new_var; /* TRUE when creating the variable */
19994+ {
19995+ if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
19996+ && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
19997+ ? name[2] : name[0]))
19998+ {
19999+ EMSG2(_("E704: Funcref variable name must start with a capital: %s"),
20000+ name);
20001+ return TRUE;
20002+ }
20003+ /* Don't allow hiding a function. When "v" is not NULL we might be
20004+ * assigning another function to the same var, the type is checked
20005+ * below. */
20006+ if (new_var && function_exists(name))
20007+ {
20008+ EMSG2(_("E705: Variable name conflicts with existing function: %s"),
20009+ name);
20010+ return TRUE;
20011+ }
20012+ return FALSE;
20013+ }
20014+
20015+ /*
20016+ * Check if a variable name is valid.
20017+ * Return FALSE and give an error if not.
20018+ */
20019+ static int
20020+ valid_varname(varname)
20021+ char_u *varname;
20022+ {
20023+ char_u *p;
20024+
20025+ for (p = varname; *p != NUL; ++p)
20026+ if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
20027+ && *p != AUTOLOAD_CHAR)
20028+ {
20029+ EMSG2(_(e_illvar), varname);
20030+ return FALSE;
20031+ }
20032+ return TRUE;
20033+ }
20034+
1998420035/*
1998520036 * Return TRUE if typeval "tv" is set to be locked (immutable).
1998620037 * Also give an error message, using "name".
0 commit comments