patch 9.2.0476: pattern completion leaks memory on alloc failures

Problem:  copy_substring_from_pos() leaked on ga_grow() failures,
          expand_pattern_in_buf() leaked "match" on ga_grow() failure,
          fuzzy_match_str_with_pos() ignored ga_grow() failures
Solution: Route failures through cleanup paths, check ga_grow before
          writing to ga_data (glepnir)

closes: #20203

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir
2026-05-12 17:40:19 +00:00
committed by Christian Brabandt
parent 78302b7b4a
commit 38237411e4
3 changed files with 14 additions and 4 deletions
+6 -3
View File
@@ -4914,7 +4914,7 @@ copy_substring_from_pos(pos_T *start, pos_T *end, char_u **match,
line = ml_get(lnum);
linelen = (int)ml_get_len(lnum);
if (ga_grow(&ga, linelen + 2) != OK)
return FAIL;
goto fail;
ga_concat_len(&ga, line, linelen);
if (exacttext)
GA_CONCAT_LITERAL(&ga, "\\n");
@@ -5141,8 +5141,8 @@ expand_pattern_in_buf(
}
// Extract the matching text prepended to completed word
if (!copy_substring_from_pos(&cur_match_pos, &end_match_pos, &full_match,
&word_end_pos))
if (copy_substring_from_pos(&cur_match_pos, &end_match_pos, &full_match,
&word_end_pos) == FAIL)
break;
if (exacttext)
@@ -5183,7 +5183,10 @@ expand_pattern_in_buf(
if (match != NULL)
{
if (ga_grow(&ga, 1) == FAIL)
{
VIM_CLEAR(match);
goto cleanup;
}
((char_u **)ga.ga_data)[ga.ga_len++] = match;
if (ga.ga_len > TAG_MANY)
break;
+6 -1
View File
@@ -690,7 +690,12 @@ fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED)
{
if (!VIM_ISWHITE(PTR2CHAR(p)))
{
ga_grow(match_positions, 1);
if (ga_grow(match_positions, 1) == FAIL)
{
ga_clear(match_positions);
vim_free(match_positions);
return NULL;
}
((int_u *)match_positions->ga_data)[match_positions->ga_len] =
matches[j];
match_positions->ga_len++;
+2
View File
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
476,
/**/
475,
/**/