comparison src/eval.c @ 2739:2bd574a2ef1c v7.3.146

updated for version 7.3.146 Problem: It's possible to assign to a read-only member of a dict. It's possible to create a global variable "0". (ZyX) It's possible to add a v: variable with ":let v:.name = 1". Solution: Add check for dict item being read-only. Check the name of g: variables. Disallow adding v: variables.
author Bram Moolenaar <bram@vim.org>
date Sun, 27 Mar 2011 16:03:15 +0200
parents 3ea3dcbf2cd6
children 6146c9859f65
comparison
equal deleted inserted replaced
2738:01b806a03556 2739:2bd574a2ef1c
787 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first)); 787 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first));
788 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first)); 788 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first));
789 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 789 static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
790 static int var_check_ro __ARGS((int flags, char_u *name)); 790 static int var_check_ro __ARGS((int flags, char_u *name));
791 static int var_check_fixed __ARGS((int flags, char_u *name)); 791 static int var_check_fixed __ARGS((int flags, char_u *name));
792 static int var_check_func_name __ARGS((char_u *name, int new_var));
793 static int valid_varname __ARGS((char_u *varname));
792 static int tv_check_lock __ARGS((int lock, char_u *name)); 794 static int tv_check_lock __ARGS((int lock, char_u *name));
793 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 795 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID));
794 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 796 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
795 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 797 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd));
796 static int eval_fname_script __ARGS((char_u *p)); 798 static int eval_fname_script __ARGS((char_u *p));
2714 } 2716 }
2715 } 2717 }
2716 lp->ll_list = NULL; 2718 lp->ll_list = NULL;
2717 lp->ll_dict = lp->ll_tv->vval.v_dict; 2719 lp->ll_dict = lp->ll_tv->vval.v_dict;
2718 lp->ll_di = dict_find(lp->ll_dict, key, len); 2720 lp->ll_di = dict_find(lp->ll_dict, key, len);
2721
2722 /* When assigning to g: check that a function and variable name is
2723 * valid. */
2724 if (rettv != NULL && lp->ll_dict == &globvardict)
2725 {
2726 if (rettv->v_type == VAR_FUNC
2727 && var_check_func_name(key, lp->ll_di == NULL))
2728 return NULL;
2729 if (!valid_varname(key))
2730 return NULL;
2731 }
2732
2719 if (lp->ll_di == NULL) 2733 if (lp->ll_di == NULL)
2720 { 2734 {
2735 /* Can't add "v:" variable. */
2736 if (lp->ll_dict == &vimvardict)
2737 {
2738 EMSG2(_(e_illvar), name);
2739 return NULL;
2740 }
2741
2721 /* Key does not exist in dict: may need to add it. */ 2742 /* Key does not exist in dict: may need to add it. */
2722 if (*p == '[' || *p == '.' || unlet) 2743 if (*p == '[' || *p == '.' || unlet)
2723 { 2744 {
2724 if (!quiet) 2745 if (!quiet)
2725 EMSG2(_(e_dictkey), key); 2746 EMSG2(_(e_dictkey), key);
2735 clear_tv(&var1); 2756 clear_tv(&var1);
2736 if (lp->ll_newkey == NULL) 2757 if (lp->ll_newkey == NULL)
2737 p = NULL; 2758 p = NULL;
2738 break; 2759 break;
2739 } 2760 }
2761 /* existing variable, need to check if it can be changed */
2762 else if (var_check_ro(lp->ll_di->di_flags, name))
2763 return NULL;
2764
2740 if (len == -1) 2765 if (len == -1)
2741 clear_tv(&var1); 2766 clear_tv(&var1);
2742 lp->ll_tv = &lp->ll_di->di_tv; 2767 lp->ll_tv = &lp->ll_di->di_tv;
2743 } 2768 }
2744 else 2769 else
19784 int copy; /* make copy of value in "tv" */ 19809 int copy; /* make copy of value in "tv" */
19785 { 19810 {
19786 dictitem_T *v; 19811 dictitem_T *v;
19787 char_u *varname; 19812 char_u *varname;
19788 hashtab_T *ht; 19813 hashtab_T *ht;
19789 char_u *p;
19790 19814
19791 ht = find_var_ht(name, &varname); 19815 ht = find_var_ht(name, &varname);
19792 if (ht == NULL || *varname == NUL) 19816 if (ht == NULL || *varname == NUL)
19793 { 19817 {
19794 EMSG2(_(e_illvar), name); 19818 EMSG2(_(e_illvar), name);
19795 return; 19819 return;
19796 } 19820 }
19797 v = find_var_in_ht(ht, varname, TRUE); 19821 v = find_var_in_ht(ht, varname, TRUE);
19798 19822
19799 if (tv->v_type == VAR_FUNC) 19823 if (tv->v_type == VAR_FUNC && var_check_func_name(name, v == NULL))
19800 { 19824 return;
19801 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
19802 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
19803 ? name[2] : name[0]))
19804 {
19805 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name);
19806 return;
19807 }
19808 /* Don't allow hiding a function. When "v" is not NULL we might be
19809 * assigning another function to the same var, the type is checked
19810 * below. */
19811 if (v == NULL && function_exists(name))
19812 {
19813 EMSG2(_("E705: Variable name conflicts with existing function: %s"),
19814 name);
19815 return;
19816 }
19817 }
19818 19825
19819 if (v != NULL) 19826 if (v != NULL)
19820 { 19827 {
19821 /* existing variable, need to clear the value */ 19828 /* existing variable, need to clear the value */
19822 if (var_check_ro(v->di_flags, name) 19829 if (var_check_ro(v->di_flags, name)
19878 EMSG2(_(e_illvar), name); 19885 EMSG2(_(e_illvar), name);
19879 return; 19886 return;
19880 } 19887 }
19881 19888
19882 /* Make sure the variable name is valid. */ 19889 /* Make sure the variable name is valid. */
19883 for (p = varname; *p != NUL; ++p) 19890 if (!valid_varname(varname))
19884 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 19891 return;
19885 && *p != AUTOLOAD_CHAR)
19886 {
19887 EMSG2(_(e_illvar), varname);
19888 return;
19889 }
19890 19892
19891 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19893 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
19892 + STRLEN(varname))); 19894 + STRLEN(varname)));
19893 if (v == NULL) 19895 if (v == NULL)
19894 return; 19896 return;
19946 { 19948 {
19947 EMSG2(_("E795: Cannot delete variable %s"), name); 19949 EMSG2(_("E795: Cannot delete variable %s"), name);
19948 return TRUE; 19950 return TRUE;
19949 } 19951 }
19950 return FALSE; 19952 return FALSE;
19953 }
19954
19955 /*
19956 * Check if a funcref is assigned to a valid variable name.
19957 * Return TRUE and give an error if not.
19958 */
19959 static int
19960 var_check_func_name(name, new_var)
19961 char_u *name; /* points to start of variable name */
19962 int new_var; /* TRUE when creating the variable */
19963 {
19964 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
19965 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
19966 ? name[2] : name[0]))
19967 {
19968 EMSG2(_("E704: Funcref variable name must start with a capital: %s"),
19969 name);
19970 return TRUE;
19971 }
19972 /* Don't allow hiding a function. When "v" is not NULL we might be
19973 * assigning another function to the same var, the type is checked
19974 * below. */
19975 if (new_var && function_exists(name))
19976 {
19977 EMSG2(_("E705: Variable name conflicts with existing function: %s"),
19978 name);
19979 return TRUE;
19980 }
19981 return FALSE;
19982 }
19983
19984 /*
19985 * Check if a variable name is valid.
19986 * Return FALSE and give an error if not.
19987 */
19988 static int
19989 valid_varname(varname)
19990 char_u *varname;
19991 {
19992 char_u *p;
19993
19994 for (p = varname; *p != NUL; ++p)
19995 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
19996 && *p != AUTOLOAD_CHAR)
19997 {
19998 EMSG2(_(e_illvar), varname);
19999 return FALSE;
20000 }
20001 return TRUE;
19951 } 20002 }
19952 20003
19953 /* 20004 /*
19954 * Return TRUE if typeval "tv" is set to be locked (immutable). 20005 * Return TRUE if typeval "tv" is set to be locked (immutable).
19955 * Also give an error message, using "name". 20006 * Also give an error message, using "name".