]>
Commit | Line | Data |
---|---|---|
48112765 AG |
1 | To: vim-dev@vim.org |
2 | Subject: Patch 6.2.369 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=ISO-8859-1 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 6.2.369 | |
11 | Problem: Various memory leaks: when using globpath(), when searching for | |
12 | help tags files, when defining a function inside a function, when | |
13 | giving an error message through an exception, for the final "." | |
14 | line in ":append", in expression "cond ? a : b" that fails and for | |
15 | missing ")" in an expression. Using NULL pointer when adding | |
16 | first user command and for pointer computations with regexp. | |
17 | (tests by Dominique Pelle) | |
18 | Solution: Fix the leaks by freeing the allocated memory. Don't use the | |
19 | array of user commands when there are no entries. Use a macro | |
20 | instead of a function call for saving and restoring regexp states. | |
21 | Files: src/eval.c, src/ex_cmds.c, src/ex_docmd.c, src/ex_getln.c, | |
22 | src/misc2.c, src/regexp.c, src/screen.c, src/tag.c | |
23 | ||
24 | ||
25 | *** ../vim-6.2.368/src/eval.c Fri Feb 20 22:11:01 2004 | |
26 | --- src/eval.c Wed Mar 17 11:38:47 2004 | |
27 | *************** | |
28 | *** 1690,1695 **** | |
29 | --- 1690,1697 ---- | |
30 | if ((*arg)[0] != ':') | |
31 | { | |
32 | EMSG(_("E109: Missing ':' after '?'")); | |
33 | + if (evaluate && result) | |
34 | + clear_var(retvar); | |
35 | return FAIL; | |
36 | } | |
37 | ||
38 | *************** | |
39 | *** 1698,1704 **** | |
40 | --- 1700,1710 ---- | |
41 | */ | |
42 | *arg = skipwhite(*arg + 1); | |
43 | if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ | |
44 | + { | |
45 | + if (evaluate && result) | |
46 | + clear_var(retvar); | |
47 | return FAIL; | |
48 | + } | |
49 | if (evaluate && !result) | |
50 | *retvar = var2; | |
51 | } | |
52 | *************** | |
53 | *** 1734,1743 **** | |
54 | /* | |
55 | * Repeat until there is no following "||". | |
56 | */ | |
57 | while ((*arg)[0] == '|' && (*arg)[1] == '|') | |
58 | { | |
59 | - result = FALSE; | |
60 | - first = TRUE; | |
61 | if (evaluate && first) | |
62 | { | |
63 | if (get_var_number(retvar) != 0) | |
64 | --- 1740,1749 ---- | |
65 | /* | |
66 | * Repeat until there is no following "||". | |
67 | */ | |
68 | + first = TRUE; | |
69 | + result = FALSE; | |
70 | while ((*arg)[0] == '|' && (*arg)[1] == '|') | |
71 | { | |
72 | if (evaluate && first) | |
73 | { | |
74 | if (get_var_number(retvar) != 0) | |
75 | *************** | |
76 | *** 1800,1809 **** | |
77 | /* | |
78 | * Repeat until there is no following "&&". | |
79 | */ | |
80 | while ((*arg)[0] == '&' && (*arg)[1] == '&') | |
81 | { | |
82 | - result = TRUE; | |
83 | - first = TRUE; | |
84 | if (evaluate && first) | |
85 | { | |
86 | if (get_var_number(retvar) == 0) | |
87 | --- 1806,1815 ---- | |
88 | /* | |
89 | * Repeat until there is no following "&&". | |
90 | */ | |
91 | + first = TRUE; | |
92 | + result = TRUE; | |
93 | while ((*arg)[0] == '&' && (*arg)[1] == '&') | |
94 | { | |
95 | if (evaluate && first) | |
96 | { | |
97 | if (get_var_number(retvar) == 0) | |
98 | *************** | |
99 | *** 2306,2311 **** | |
100 | --- 2312,2318 ---- | |
101 | else if (ret == OK) | |
102 | { | |
103 | EMSG(_("E110: Missing ')'")); | |
104 | + clear_var(retvar); | |
105 | ret = FAIL; | |
106 | } | |
107 | break; | |
108 | *************** | |
109 | *** 2331,2337 **** | |
110 | --- 2338,2348 ---- | |
111 | * aborting on error, or when an interrupt occurred or | |
112 | * an exception was thrown but not caught. */ | |
113 | if (aborting()) | |
114 | + { | |
115 | + if (ret == OK) | |
116 | + clear_var(retvar); | |
117 | ret = FAIL; | |
118 | + } | |
119 | } | |
120 | else if (evaluate) | |
121 | ret = get_var_var(s, len, retvar); | |
122 | *************** | |
123 | *** 2364,2369 **** | |
124 | --- 2375,2381 ---- | |
125 | { | |
126 | EMSG(_("E111: Missing ']'")); | |
127 | clear_var(retvar); | |
128 | + clear_var(&var2); | |
129 | return FAIL; | |
130 | } | |
131 | ||
132 | *************** | |
133 | *** 6929,6941 **** | |
134 | int slen; | |
135 | ||
136 | p = get_var_string(&argvars[0]); | |
137 | n = get_var_number(&argvars[1]); | |
138 | if (argvars[2].var_type != VAR_UNKNOWN) | |
139 | len = get_var_number(&argvars[2]); | |
140 | else | |
141 | ! len = (int)STRLEN(p) - n; | |
142 | ||
143 | - slen = (int)STRLEN(p); | |
144 | /* | |
145 | * Only return the overlap between the specified part and the actual | |
146 | * string. | |
147 | --- 6941,6954 ---- | |
148 | int slen; | |
149 | ||
150 | p = get_var_string(&argvars[0]); | |
151 | + slen = (int)STRLEN(p); | |
152 | + | |
153 | n = get_var_number(&argvars[1]); | |
154 | if (argvars[2].var_type != VAR_UNKNOWN) | |
155 | len = get_var_number(&argvars[2]); | |
156 | else | |
157 | ! len = slen - n; /* default len: all bytes that are available. */ | |
158 | ||
159 | /* | |
160 | * Only return the overlap between the specified part and the actual | |
161 | * string. | |
162 | *************** | |
163 | *** 8920,8926 **** | |
164 | p += eval_fname_script(p); | |
165 | if (ASCII_ISALPHA(*p)) | |
166 | { | |
167 | ! (void)trans_function_name(&p, TRUE, FALSE); | |
168 | if (*skipwhite(p) == '(') | |
169 | { | |
170 | ++nesting; | |
171 | --- 8933,8939 ---- | |
172 | p += eval_fname_script(p); | |
173 | if (ASCII_ISALPHA(*p)) | |
174 | { | |
175 | ! vim_free(trans_function_name(&p, TRUE, FALSE)); | |
176 | if (*skipwhite(p) == '(') | |
177 | { | |
178 | ++nesting; | |
179 | *** ../vim-6.2.368/src/ex_cmds.c Mon Mar 15 12:33:19 2004 | |
180 | --- src/ex_cmds.c Wed Mar 17 10:20:59 2004 | |
181 | *************** | |
182 | *** 3238,3248 **** | |
183 | #endif | |
184 | NUL, eap->cookie, 0); | |
185 | lines_left = Rows - 1; | |
186 | ! if (theline == NULL || (theline[0] == '.' && theline[1] == NUL)) | |
187 | break; | |
188 | ||
189 | - if (!did_undo && u_save(lnum, lnum + 1) == FAIL) | |
190 | - break; | |
191 | did_undo = TRUE; | |
192 | ml_append(lnum, theline, (colnr_T)0, FALSE); | |
193 | appended_lines_mark(lnum, 1L); | |
194 | --- 3238,3250 ---- | |
195 | #endif | |
196 | NUL, eap->cookie, 0); | |
197 | lines_left = Rows - 1; | |
198 | ! if (theline == NULL || (theline[0] == '.' && theline[1] == NUL) | |
199 | ! || (!did_undo && u_save(lnum, lnum + 1) == FAIL)) | |
200 | ! { | |
201 | ! vim_free(theline); | |
202 | break; | |
203 | + } | |
204 | ||
205 | did_undo = TRUE; | |
206 | ml_append(lnum, theline, (colnr_T)0, FALSE); | |
207 | appended_lines_mark(lnum, 1L); | |
208 | *** ../vim-6.2.368/src/ex_docmd.c Mon Mar 8 15:22:09 2004 | |
209 | --- src/ex_docmd.c Tue Mar 16 12:00:49 2004 | |
210 | *************** | |
211 | *** 1261,1266 **** | |
212 | --- 1261,1267 ---- | |
213 | emsg(p); | |
214 | vim_free(p); | |
215 | } | |
216 | + vim_free(sourcing_name); | |
217 | sourcing_name = saved_sourcing_name; | |
218 | sourcing_lnum = saved_sourcing_lnum; | |
219 | } | |
220 | *************** | |
221 | *** 2650,2659 **** | |
222 | gap = &curbuf->b_ucmds; | |
223 | for (;;) | |
224 | { | |
225 | ! cmd = USER_CMD_GA(gap, 0); | |
226 | ! | |
227 | ! for (j = 0; j < gap->ga_len; ++j, ++cmd) | |
228 | { | |
229 | cp = eap->cmd; | |
230 | np = cmd->uc_name; | |
231 | k = 0; | |
232 | --- 2649,2657 ---- | |
233 | gap = &curbuf->b_ucmds; | |
234 | for (;;) | |
235 | { | |
236 | ! for (j = 0; j < gap->ga_len; ++j) | |
237 | { | |
238 | + cmd = USER_CMD_GA(gap, j); | |
239 | cp = eap->cmd; | |
240 | np = cmd->uc_name; | |
241 | k = 0; | |
242 | *************** | |
243 | *** 4579,4585 **** | |
244 | char_u *compl_arg; | |
245 | int force; | |
246 | { | |
247 | ! ucmd_T *cmd; | |
248 | char_u *p; | |
249 | int i; | |
250 | int cmp = 1; | |
251 | --- 4577,4583 ---- | |
252 | char_u *compl_arg; | |
253 | int force; | |
254 | { | |
255 | ! ucmd_T *cmd = NULL; | |
256 | char_u *p; | |
257 | int i; | |
258 | int cmp = 1; | |
259 | *************** | |
260 | *** 4607,4619 **** | |
261 | else | |
262 | gap = &ucmds; | |
263 | ||
264 | ! /* Search for the command */ | |
265 | ! cmd = USER_CMD_GA(gap, 0); | |
266 | ! i = 0; | |
267 | ! while (i < gap->ga_len) | |
268 | { | |
269 | ! size_t len = STRLEN(cmd->uc_name); | |
270 | ||
271 | cmp = STRNCMP(name, cmd->uc_name, name_len); | |
272 | if (cmp == 0) | |
273 | { | |
274 | --- 4605,4617 ---- | |
275 | else | |
276 | gap = &ucmds; | |
277 | ||
278 | ! /* Search for the command in the already defined commands. */ | |
279 | ! for (i = 0; i < gap->ga_len; ++i) | |
280 | { | |
281 | ! size_t len; | |
282 | ||
283 | + cmd = USER_CMD_GA(gap, i); | |
284 | + len = STRLEN(cmd->uc_name); | |
285 | cmp = STRNCMP(name, cmd->uc_name, name_len); | |
286 | if (cmp == 0) | |
287 | { | |
288 | *************** | |
289 | *** 4639,4647 **** | |
290 | /* Stop as soon as we pass the name to add */ | |
291 | if (cmp < 0) | |
292 | break; | |
293 | - | |
294 | - ++cmd; | |
295 | - ++i; | |
296 | } | |
297 | ||
298 | /* Extend the array unless we're replacing an existing command */ | |
299 | --- 4637,4642 ---- | |
300 | *************** | |
301 | *** 5124,5143 **** | |
302 | exarg_T *eap; | |
303 | { | |
304 | int i = 0; | |
305 | ! ucmd_T *cmd; | |
306 | int cmp = -1; | |
307 | garray_T *gap; | |
308 | ||
309 | gap = &curbuf->b_ucmds; | |
310 | for (;;) | |
311 | { | |
312 | - cmd = USER_CMD_GA(gap, 0); | |
313 | for (i = 0; i < gap->ga_len; ++i) | |
314 | { | |
315 | cmp = STRCMP(eap->arg, cmd->uc_name); | |
316 | if (cmp <= 0) | |
317 | break; | |
318 | - ++cmd; | |
319 | } | |
320 | if (gap == &ucmds || cmp == 0) | |
321 | break; | |
322 | --- 5119,5137 ---- | |
323 | exarg_T *eap; | |
324 | { | |
325 | int i = 0; | |
326 | ! ucmd_T *cmd = NULL; | |
327 | int cmp = -1; | |
328 | garray_T *gap; | |
329 | ||
330 | gap = &curbuf->b_ucmds; | |
331 | for (;;) | |
332 | { | |
333 | for (i = 0; i < gap->ga_len; ++i) | |
334 | { | |
335 | + cmd = USER_CMD_GA(gap, i); | |
336 | cmp = STRCMP(eap->arg, cmd->uc_name); | |
337 | if (cmp <= 0) | |
338 | break; | |
339 | } | |
340 | if (gap == &ucmds || cmp == 0) | |
341 | break; | |
342 | *** ../vim-6.2.368/src/ex_getln.c Sun Feb 29 21:06:13 2004 | |
343 | --- src/ex_getln.c Tue Mar 16 10:41:32 2004 | |
344 | *************** | |
345 | *** 2048,2055 **** | |
346 | redrawcmd_preedit() | |
347 | { | |
348 | if ((State & CMDLINE) | |
349 | ! && xic != NULL && im_get_status() && !p_imdisable | |
350 | ! && preedit_start_col != MAXCOL) | |
351 | { | |
352 | int cmdpos = 0; | |
353 | int cmdspos; | |
354 | --- 2048,2057 ---- | |
355 | redrawcmd_preedit() | |
356 | { | |
357 | if ((State & CMDLINE) | |
358 | ! && xic != NULL | |
359 | ! && im_get_status() | |
360 | ! && !p_imdisable | |
361 | ! && preedit_start_col != MAXCOL) | |
362 | { | |
363 | int cmdpos = 0; | |
364 | int cmdspos; | |
365 | *************** | |
366 | *** 4057,4062 **** | |
367 | --- 4059,4065 ---- | |
368 | ga.ga_len += len; | |
369 | ga.ga_room -= len; | |
370 | } | |
371 | + FreeWild(num_p, p); | |
372 | } | |
373 | } | |
374 | } | |
375 | *** ../vim-6.2.368/src/misc2.c Mon Mar 15 12:44:12 2004 | |
376 | --- src/misc2.c Tue Mar 16 11:07:16 2004 | |
377 | *************** | |
378 | *** 1500,1506 **** | |
379 | ga_init(gap); | |
380 | } | |
381 | ||
382 | - #if defined(FEAT_EVAL) || defined(PROTO) | |
383 | /* | |
384 | * Clear a growing array that contains a list of strings. | |
385 | */ | |
386 | --- 1500,1505 ---- | |
387 | *************** | |
388 | *** 1514,1520 **** | |
389 | vim_free(((char_u **)(gap->ga_data))[i]); | |
390 | ga_clear(gap); | |
391 | } | |
392 | - #endif | |
393 | ||
394 | /* | |
395 | * Initialize a growing array. Don't forget to set ga_itemsize and | |
396 | --- 1513,1518 ---- | |
397 | *** ../vim-6.2.368/src/regexp.c Sun Feb 15 13:49:38 2004 | |
398 | --- src/regexp.c Tue Mar 16 11:34:06 2004 | |
399 | *************** | |
400 | *** 2611,2618 **** | |
401 | static void reg_save __ARGS((regsave_T *save)); | |
402 | static void reg_restore __ARGS((regsave_T *save)); | |
403 | static int reg_save_equal __ARGS((regsave_T *save)); | |
404 | ! static void save_se __ARGS((save_se_T *savep, lpos_T *posp, char_u **pp)); | |
405 | ! static void restore_se __ARGS((save_se_T *savep, lpos_T *posp, char_u **pp)); | |
406 | static int re_num_cmp __ARGS((long_u val, char_u *scan)); | |
407 | static int regmatch __ARGS((char_u *prog)); | |
408 | static int regrepeat __ARGS((char_u *p, long maxcount)); | |
409 | --- 2611,2630 ---- | |
410 | static void reg_save __ARGS((regsave_T *save)); | |
411 | static void reg_restore __ARGS((regsave_T *save)); | |
412 | static int reg_save_equal __ARGS((regsave_T *save)); | |
413 | ! static void save_se_multi __ARGS((save_se_T *savep, lpos_T *posp)); | |
414 | ! static void save_se_one __ARGS((save_se_T *savep, char_u **pp)); | |
415 | ! | |
416 | ! /* Save the sub-expressions before attempting a match. */ | |
417 | ! #define save_se(savep, posp, pp) \ | |
418 | ! REG_MULTI ? save_se_multi((savep), (posp)) : save_se_one((savep), (pp)) | |
419 | ! | |
420 | ! /* After a failed match restore the sub-expressions. */ | |
421 | ! #define restore_se(savep, posp, pp) { \ | |
422 | ! if (REG_MULTI) \ | |
423 | ! *(posp) = (savep)->se_u.pos; \ | |
424 | ! else \ | |
425 | ! *(pp) = (savep)->se_u.ptr; } | |
426 | ! | |
427 | static int re_num_cmp __ARGS((long_u val, char_u *scan)); | |
428 | static int regmatch __ARGS((char_u *prog)); | |
429 | static int regrepeat __ARGS((char_u *p, long maxcount)); | |
430 | *************** | |
431 | *** 4747,4786 **** | |
432 | * Tentatively set the sub-expression start to the current position (after | |
433 | * calling regmatch() they will have changed). Need to save the existing | |
434 | * values for when there is no match. | |
435 | ! * Use pointer or position, depending on REG_MULTI. | |
436 | */ | |
437 | static void | |
438 | ! save_se(savep, posp, pp) | |
439 | save_se_T *savep; | |
440 | lpos_T *posp; | |
441 | - char_u **pp; | |
442 | { | |
443 | ! if (REG_MULTI) | |
444 | ! { | |
445 | ! savep->se_u.pos = *posp; | |
446 | ! posp->lnum = reglnum; | |
447 | ! posp->col = (colnr_T)(reginput - regline); | |
448 | ! } | |
449 | ! else | |
450 | ! { | |
451 | ! savep->se_u.ptr = *pp; | |
452 | ! *pp = reginput; | |
453 | ! } | |
454 | } | |
455 | ||
456 | - /* | |
457 | - * We were wrong, restore the sub-expressions. | |
458 | - */ | |
459 | static void | |
460 | ! restore_se(savep, posp, pp) | |
461 | save_se_T *savep; | |
462 | - lpos_T *posp; | |
463 | char_u **pp; | |
464 | { | |
465 | ! if (REG_MULTI) | |
466 | ! *posp = savep->se_u.pos; | |
467 | ! else | |
468 | ! *pp = savep->se_u.ptr; | |
469 | } | |
470 | ||
471 | /* | |
472 | --- 4759,4784 ---- | |
473 | * Tentatively set the sub-expression start to the current position (after | |
474 | * calling regmatch() they will have changed). Need to save the existing | |
475 | * values for when there is no match. | |
476 | ! * Use se_save() to use pointer (save_se_multi()) or position (save_se_one()), | |
477 | ! * depending on REG_MULTI. | |
478 | */ | |
479 | static void | |
480 | ! save_se_multi(savep, posp) | |
481 | save_se_T *savep; | |
482 | lpos_T *posp; | |
483 | { | |
484 | ! savep->se_u.pos = *posp; | |
485 | ! posp->lnum = reglnum; | |
486 | ! posp->col = (colnr_T)(reginput - regline); | |
487 | } | |
488 | ||
489 | static void | |
490 | ! save_se_one(savep, pp) | |
491 | save_se_T *savep; | |
492 | char_u **pp; | |
493 | { | |
494 | ! savep->se_u.ptr = *pp; | |
495 | ! *pp = reginput; | |
496 | } | |
497 | ||
498 | /* | |
499 | *** ../vim-6.2.368/src/screen.c Tue Mar 16 15:35:40 2004 | |
500 | --- src/screen.c Wed Mar 17 12:40:59 2004 | |
501 | *************** | |
502 | *** 1599,1604 **** | |
503 | --- 1599,1613 ---- | |
504 | wp->w_lines_valid = wp->w_height; | |
505 | for (i = wp->w_lines_valid; i - j >= idx; --i) | |
506 | wp->w_lines[i] = wp->w_lines[i - j]; | |
507 | + | |
508 | + /* The w_lines[] entries for inserted lines are | |
509 | + * now invalid, but wl_size may be used above. | |
510 | + * Reset to zero. */ | |
511 | + while (i >= idx) | |
512 | + { | |
513 | + wp->w_lines[i].wl_size = 0; | |
514 | + wp->w_lines[i--].wl_valid = FALSE; | |
515 | + } | |
516 | } | |
517 | } | |
518 | } | |
519 | *** ../vim-6.2.368/src/tag.c Sun Feb 29 21:06:13 2004 | |
520 | --- src/tag.c Tue Mar 16 11:06:16 2004 | |
521 | *************** | |
522 | *** 2226,2232 **** | |
523 | * For a help window find "doc/tags" and "doc/tags-??" in all | |
524 | * directories in 'runtimepath'. | |
525 | */ | |
526 | ! ga_clear(&tag_fnames); | |
527 | ga_init2(&tag_fnames, sizeof(char_u *), 10); | |
528 | do_in_runtimepath((char_u *) | |
529 | #ifdef FEAT_MULTI_LANG | |
530 | --- 2226,2232 ---- | |
531 | * For a help window find "doc/tags" and "doc/tags-??" in all | |
532 | * directories in 'runtimepath'. | |
533 | */ | |
534 | ! ga_clear_strings(&tag_fnames); | |
535 | ga_init2(&tag_fnames, sizeof(char_u *), 10); | |
536 | do_in_runtimepath((char_u *) | |
537 | #ifdef FEAT_MULTI_LANG | |
538 | *** ../vim-6.2.368/src/version.c Wed Mar 17 09:54:22 2004 | |
539 | --- src/version.c Wed Mar 17 13:04:59 2004 | |
540 | *************** | |
541 | *** 639,640 **** | |
542 | --- 639,642 ---- | |
543 | { /* Add new patch number below this line */ | |
544 | + /**/ | |
545 | + 369, | |
546 | /**/ | |
547 | ||
548 | -- | |
549 | I started out with nothing, and I still have most of it. | |
550 | -- Michael Davis -- "Tonight Show" | |
551 | ||
552 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
553 | /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
554 | \\\ Project leader for A-A-P -- http://www.A-A-P.org /// | |
555 | \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html /// |