]>
Commit | Line | Data |
---|---|---|
ba6abda2 ER |
1 | To: vim_dev@googlegroups.com |
2 | Subject: Patch 7.3.146 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.3.146 | |
11 | Problem: It's possible to assign to a read-only member of a dict. | |
12 | It's possible to create a global variable "0". (ZyX) | |
13 | It's possible to add a v: variable with ":let v:.name = 1". | |
14 | Solution: Add check for dict item being read-only. | |
15 | Check the name of g: variables. | |
16 | Disallow adding v: variables. | |
17 | Files: src/eval.c | |
18 | ||
19 | ||
20 | *** ../vim-7.3.145/src/eval.c 2011-02-01 13:48:47.000000000 +0100 | |
21 | --- src/eval.c 2011-03-27 15:56:44.000000000 +0200 | |
22 | *************** | |
23 | *** 789,794 **** | |
24 | --- 789,796 ---- | |
25 | static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); | |
26 | static int var_check_ro __ARGS((int flags, char_u *name)); | |
27 | static int var_check_fixed __ARGS((int flags, char_u *name)); | |
28 | + static int var_check_func_name __ARGS((char_u *name, int new_var)); | |
29 | + static int valid_varname __ARGS((char_u *varname)); | |
30 | static int tv_check_lock __ARGS((int lock, char_u *name)); | |
31 | static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); | |
32 | static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); | |
33 | *************** | |
34 | *** 2716,2723 **** | |
35 | --- 2718,2744 ---- | |
36 | lp->ll_list = NULL; | |
37 | lp->ll_dict = lp->ll_tv->vval.v_dict; | |
38 | lp->ll_di = dict_find(lp->ll_dict, key, len); | |
39 | + | |
40 | + /* When assigning to g: check that a function and variable name is | |
41 | + * valid. */ | |
42 | + if (rettv != NULL && lp->ll_dict == &globvardict) | |
43 | + { | |
44 | + if (rettv->v_type == VAR_FUNC | |
45 | + && var_check_func_name(key, lp->ll_di == NULL)) | |
46 | + return NULL; | |
47 | + if (!valid_varname(key)) | |
48 | + return NULL; | |
49 | + } | |
50 | + | |
51 | if (lp->ll_di == NULL) | |
52 | { | |
53 | + /* Can't add "v:" variable. */ | |
54 | + if (lp->ll_dict == &vimvardict) | |
55 | + { | |
56 | + EMSG2(_(e_illvar), name); | |
57 | + return NULL; | |
58 | + } | |
59 | + | |
60 | /* Key does not exist in dict: may need to add it. */ | |
61 | if (*p == '[' || *p == '.' || unlet) | |
62 | { | |
63 | *************** | |
64 | *** 2737,2742 **** | |
65 | --- 2758,2767 ---- | |
66 | p = NULL; | |
67 | break; | |
68 | } | |
69 | + /* existing variable, need to check if it can be changed */ | |
70 | + else if (var_check_ro(lp->ll_di->di_flags, name)) | |
71 | + return NULL; | |
72 | + | |
73 | if (len == -1) | |
74 | clear_tv(&var1); | |
75 | lp->ll_tv = &lp->ll_di->di_tv; | |
76 | *************** | |
77 | *** 19786,19792 **** | |
78 | dictitem_T *v; | |
79 | char_u *varname; | |
80 | hashtab_T *ht; | |
81 | - char_u *p; | |
82 | ||
83 | ht = find_var_ht(name, &varname); | |
84 | if (ht == NULL || *varname == NUL) | |
85 | --- 19811,19816 ---- | |
86 | *************** | |
87 | *** 19796,19820 **** | |
88 | } | |
89 | v = find_var_in_ht(ht, varname, TRUE); | |
90 | ||
91 | ! if (tv->v_type == VAR_FUNC) | |
92 | ! { | |
93 | ! if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') | |
94 | ! && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') | |
95 | ! ? name[2] : name[0])) | |
96 | ! { | |
97 | ! EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); | |
98 | ! return; | |
99 | ! } | |
100 | ! /* Don't allow hiding a function. When "v" is not NULL we might be | |
101 | ! * assigning another function to the same var, the type is checked | |
102 | ! * below. */ | |
103 | ! if (v == NULL && function_exists(name)) | |
104 | ! { | |
105 | ! EMSG2(_("E705: Variable name conflicts with existing function: %s"), | |
106 | ! name); | |
107 | ! return; | |
108 | ! } | |
109 | ! } | |
110 | ||
111 | if (v != NULL) | |
112 | { | |
113 | --- 19820,19827 ---- | |
114 | } | |
115 | v = find_var_in_ht(ht, varname, TRUE); | |
116 | ||
117 | ! if (tv->v_type == VAR_FUNC && var_check_func_name(name, v == NULL)) | |
118 | ! return; | |
119 | ||
120 | if (v != NULL) | |
121 | { | |
122 | *************** | |
123 | *** 19880,19892 **** | |
124 | } | |
125 | ||
126 | /* Make sure the variable name is valid. */ | |
127 | ! for (p = varname; *p != NUL; ++p) | |
128 | ! if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) | |
129 | ! && *p != AUTOLOAD_CHAR) | |
130 | ! { | |
131 | ! EMSG2(_(e_illvar), varname); | |
132 | ! return; | |
133 | ! } | |
134 | ||
135 | v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) | |
136 | + STRLEN(varname))); | |
137 | --- 19887,19894 ---- | |
138 | } | |
139 | ||
140 | /* Make sure the variable name is valid. */ | |
141 | ! if (!valid_varname(varname)) | |
142 | ! return; | |
143 | ||
144 | v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) | |
145 | + STRLEN(varname))); | |
146 | *************** | |
147 | *** 19951,19956 **** | |
148 | --- 19953,20007 ---- | |
149 | } | |
150 | ||
151 | /* | |
152 | + * Check if a funcref is assigned to a valid variable name. | |
153 | + * Return TRUE and give an error if not. | |
154 | + */ | |
155 | + static int | |
156 | + var_check_func_name(name, new_var) | |
157 | + char_u *name; /* points to start of variable name */ | |
158 | + int new_var; /* TRUE when creating the variable */ | |
159 | + { | |
160 | + if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') | |
161 | + && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') | |
162 | + ? name[2] : name[0])) | |
163 | + { | |
164 | + EMSG2(_("E704: Funcref variable name must start with a capital: %s"), | |
165 | + name); | |
166 | + return TRUE; | |
167 | + } | |
168 | + /* Don't allow hiding a function. When "v" is not NULL we might be | |
169 | + * assigning another function to the same var, the type is checked | |
170 | + * below. */ | |
171 | + if (new_var && function_exists(name)) | |
172 | + { | |
173 | + EMSG2(_("E705: Variable name conflicts with existing function: %s"), | |
174 | + name); | |
175 | + return TRUE; | |
176 | + } | |
177 | + return FALSE; | |
178 | + } | |
179 | + | |
180 | + /* | |
181 | + * Check if a variable name is valid. | |
182 | + * Return FALSE and give an error if not. | |
183 | + */ | |
184 | + static int | |
185 | + valid_varname(varname) | |
186 | + char_u *varname; | |
187 | + { | |
188 | + char_u *p; | |
189 | + | |
190 | + for (p = varname; *p != NUL; ++p) | |
191 | + if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) | |
192 | + && *p != AUTOLOAD_CHAR) | |
193 | + { | |
194 | + EMSG2(_(e_illvar), varname); | |
195 | + return FALSE; | |
196 | + } | |
197 | + return TRUE; | |
198 | + } | |
199 | + | |
200 | + /* | |
201 | * Return TRUE if typeval "tv" is set to be locked (immutable). | |
202 | * Also give an error message, using "name". | |
203 | */ | |
204 | *** ../vim-7.3.145/src/version.c 2011-03-26 18:32:00.000000000 +0100 | |
205 | --- src/version.c 2011-03-27 16:01:03.000000000 +0200 | |
206 | *************** | |
207 | *** 716,717 **** | |
208 | --- 716,719 ---- | |
209 | { /* Add new patch number below this line */ | |
210 | + /**/ | |
211 | + 146, | |
212 | /**/ | |
213 | ||
214 | -- | |
215 | ARTHUR: It is I, Arthur, son of Uther Pendragon, from the castle of Camelot. | |
216 | King of all Britons, defeator of the Saxons, sovereign of all England! | |
217 | [Pause] | |
218 | SOLDIER: Get away! | |
219 | "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD | |
220 | ||
221 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
222 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
223 | \\\ an exciting new programming language -- http://www.Zimbu.org /// | |
224 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |