neovim/neovim — pull request #1743 by oni-link (2014-12-27 09:03:54+00:00)
Title: [RFC] vim-patch: Mark patch 7.4.560 as NA

Mark patch 7.4.560 as NA

The memory leak fixed in 7.4.560 was fixed in e10670ac3bccbea707432bdb54e18639cf2e125f. We also do not need to keep `y_current->y_array` as is until done, because our memory allocations cannot fail.

Problem: Memory leak using :wviminfo. Issue 296 .
Solution: Free memory when needed. (idea by Christian Brabandt)

https://code.google.com/p/vim/source/detail?r=v7-4-560
```diff
diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -5663,6 +5663,8 @@
int	set_prev = FALSE;
char_u	*str;
char_u	**array = NULL;
+ int	new_type;
+ colnr_T	new_width;

/* We only get here (hopefully) if line[0] == '"' */
str = virp->vir_line + 1;
@@ -5695,21 +5697,25 @@
limit = 100;	/* Optimized for registers containing <= 100 lines */
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)
y_previous = y_current;
-	vim_free(y_current->y_array);
-	array = y_current->y_array =
-	(char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
+	array = (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
str = skipwhite(skiptowhite(str));
if (STRNCMP(str, "CHAR", 4) == 0)
-	y_current->y_type = MCHAR;
+	new_type = MCHAR;
else if (STRNCMP(str, "BLOCK", 5) == 0)
-	y_current->y_type = MBLOCK;
+	new_type = MBLOCK;
else
-	y_current->y_type = MLINE;
+	new_type = MLINE;
/* get the block width; if it's missing we get a zero, which is OK */
str = skipwhite(skiptowhite(str));
-	y_current->y_width = getdigits(&str);
+	new_width = getdigits(&str);
}

while (!(eof = viminfo_readline(virp))
@@ -5717,40 +5723,66 @@
{
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 *)));
+
+	if (new_array == NULL)
+	{
+	do_it = FALSE;
+	break;
+	}
for (i = 0; i < limit; i++)
-	y_current->y_array[i] = array[i];
+	new_array[i] = array[i];
vim_free(array);
+	array = new_array;
limit *= 2;
-	array = y_current->y_array;
}
str = viminfo_readstring(virp, 1, TRUE);
if (str != NULL)
array[size++] = str;
else
+	/* error, don't store the result */
do_it = FALSE;
}
}
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)
{
-	vim_free(array);
y_current->y_array = NULL;
}
-	else if (size < limit)
+	else
{
+	/* Move the lines from array[] to y_array[]. */
y_current->y_array =
(char_u **)alloc((unsigned)(size * sizeof(char_u *)));
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;
}

diff --git a/src/version.c b/src/version.c
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 560,
+/**/
559,
/**/
558,

```