0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

updated for version 7.4.560

Problem:    Memory leak using :wviminfo. Issue 296.
Solution:   Free memory when needed. (idea by Christian Brabandt)
This commit is contained in:
Bram Moolenaar 2014-12-17 21:00:49 +01:00
parent fc3f23bedf
commit e88b0033f6
2 changed files with 50 additions and 16 deletions

View File

@ -5663,6 +5663,8 @@ read_viminfo_register(virp, force)
int set_prev = FALSE; int set_prev = FALSE;
char_u *str; char_u *str;
char_u **array = NULL; char_u **array = NULL;
int new_type;
colnr_T new_width;
/* We only get here (hopefully) if line[0] == '"' */ /* We only get here (hopefully) if line[0] == '"' */
str = virp->vir_line + 1; str = virp->vir_line + 1;
@ -5695,21 +5697,25 @@ read_viminfo_register(virp, force)
limit = 100; /* Optimized for registers containing <= 100 lines */ limit = 100; /* Optimized for registers containing <= 100 lines */
if (do_it) if (do_it)
{ {
/*
* Build the new register in array[].
* y_array is kept as-is until done.
* The "do_it" flag is reset when something is wrong, in which case
* array[] needs to be freed.
*/
if (set_prev) if (set_prev)
y_previous = y_current; y_previous = y_current;
vim_free(y_current->y_array); array = (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
array = y_current->y_array =
(char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
str = skipwhite(skiptowhite(str)); str = skipwhite(skiptowhite(str));
if (STRNCMP(str, "CHAR", 4) == 0) if (STRNCMP(str, "CHAR", 4) == 0)
y_current->y_type = MCHAR; new_type = MCHAR;
else if (STRNCMP(str, "BLOCK", 5) == 0) else if (STRNCMP(str, "BLOCK", 5) == 0)
y_current->y_type = MBLOCK; new_type = MBLOCK;
else else
y_current->y_type = MLINE; new_type = MLINE;
/* get the block width; if it's missing we get a zero, which is OK */ /* get the block width; if it's missing we get a zero, which is OK */
str = skipwhite(skiptowhite(str)); str = skipwhite(skiptowhite(str));
y_current->y_width = getdigits(&str); new_width = getdigits(&str);
} }
while (!(eof = viminfo_readline(virp)) while (!(eof = viminfo_readline(virp))
@ -5717,40 +5723,66 @@ read_viminfo_register(virp, force)
{ {
if (do_it) if (do_it)
{ {
if (size >= limit) if (size == limit)
{ {
y_current->y_array = (char_u **) char_u **new_array = (char_u **)
alloc((unsigned)(limit * 2 * sizeof(char_u *))); alloc((unsigned)(limit * 2 * sizeof(char_u *)));
if (new_array == NULL)
{
do_it = FALSE;
break;
}
for (i = 0; i < limit; i++) for (i = 0; i < limit; i++)
y_current->y_array[i] = array[i]; new_array[i] = array[i];
vim_free(array); vim_free(array);
array = new_array;
limit *= 2; limit *= 2;
array = y_current->y_array;
} }
str = viminfo_readstring(virp, 1, TRUE); str = viminfo_readstring(virp, 1, TRUE);
if (str != NULL) if (str != NULL)
array[size++] = str; array[size++] = str;
else else
/* error, don't store the result */
do_it = FALSE; do_it = FALSE;
} }
} }
if (do_it) if (do_it)
{ {
/* free y_array[] */
for (i = 0; i < y_current->y_size; i++)
vim_free(y_current->y_array[i]);
vim_free(y_current->y_array);
y_current->y_type = new_type;
y_current->y_width = new_width;
y_current->y_size = size;
if (size == 0) if (size == 0)
{ {
vim_free(array);
y_current->y_array = NULL; y_current->y_array = NULL;
} }
else if (size < limit) else
{ {
/* Move the lines from array[] to y_array[]. */
y_current->y_array = y_current->y_array =
(char_u **)alloc((unsigned)(size * sizeof(char_u *))); (char_u **)alloc((unsigned)(size * sizeof(char_u *)));
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
y_current->y_array[i] = array[i]; {
vim_free(array); if (y_current->y_array == NULL)
vim_free(array[i]);
else
y_current->y_array[i] = array[i];
}
} }
y_current->y_size = size;
} }
else
{
/* Free array[] if it was filled. */
for (i = 0; i < size; i++)
vim_free(array[i]);
}
vim_free(array);
return eof; return eof;
} }

View File

@ -741,6 +741,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
560,
/**/ /**/
559, 559,
/**/ /**/