vim-patch:? Fix memory leak in readviminfo

Patch provided by Christian Brabandt
Improved by oni-link
This commit is contained in:
Joel Teichroeb
2014-12-10 13:46:04 -08:00
parent d0dcf56338
commit e10670ac3b
2 changed files with 14 additions and 19 deletions

View File

@@ -1869,7 +1869,7 @@ int viminfo_readline(vir_T *virp)
* *
* Check for a long line as written by viminfo_writestring(). * Check for a long line as written by viminfo_writestring().
* *
* Return the string in allocated memory (or NULL to indicate failure). * Return the string in allocated memory.
*/ */
char_u * char_u *
viminfo_readstring ( viminfo_readstring (
@@ -1877,6 +1877,7 @@ viminfo_readstring (
int off, /* offset for virp->vir_line */ int off, /* offset for virp->vir_line */
int convert /* convert the string */ int convert /* convert the string */
) )
FUNC_ATTR_NONNULL_RET
{ {
char_u *retval; char_u *retval;
char_u *s, *d; char_u *s, *d;

View File

@@ -4449,7 +4449,6 @@ int read_viminfo_register(vir_T *virp, int force)
int do_it = TRUE; int do_it = TRUE;
int size; int size;
int limit; int limit;
int i;
int set_prev = FALSE; int set_prev = FALSE;
char_u *str; char_u *str;
char_u **array = NULL; char_u **array = NULL;
@@ -4483,9 +4482,13 @@ int read_viminfo_register(vir_T *virp, int force)
if (do_it) { if (do_it) {
if (set_prev) if (set_prev)
y_previous = y_current; y_previous = y_current;
for (int i = 0; i < y_current->y_size; i++) {
free(y_current->y_array[i]);
}
free(y_current->y_array); free(y_current->y_array);
array = y_current->y_array = array = xmalloc(limit * sizeof(char_u *));
(char_u **)xmalloc(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; y_current->y_type = MCHAR;
@@ -4502,30 +4505,21 @@ int read_viminfo_register(vir_T *virp, int force)
&& (virp->vir_line[0] == TAB || virp->vir_line[0] == '<')) { && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<')) {
if (do_it) { if (do_it) {
if (size >= limit) { if (size >= limit) {
y_current->y_array = (char_u **)xmalloc(limit * 2 * sizeof(char_u *));
for (i = 0; i < limit; i++)
y_current->y_array[i] = array[i];
free(array);
limit *= 2; limit *= 2;
array = y_current->y_array; array = xrealloc(array, limit * sizeof(char_u *));
} }
str = viminfo_readstring(virp, 1, TRUE); array[size++] = viminfo_readstring(virp, 1, TRUE);
if (str != NULL)
array[size++] = str;
else
do_it = FALSE;
} }
} }
if (do_it) { if (do_it) {
if (size == 0) { if (size == 0) {
free(array); free(array);
y_current->y_array = NULL; y_current->y_array = NULL;
} else if (size < limit) { } else if (size < limit) {
y_current->y_array = y_current->y_array = xrealloc(array, size * sizeof(char_u *));
(char_u **)xmalloc(size * sizeof(char_u *)); } else {
for (i = 0; i < size; i++) y_current->y_array = array;
y_current->y_array[i] = array[i];
free(array);
} }
y_current->y_size = size; y_current->y_size = size;
} }