From: glepnir Date: Tue, 12 May 2026 17:40:19 +0000 (+0000) Subject: patch 9.2.0476: pattern completion leaks memory on alloc failures X-Git-Tag: v9.2.0476^0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=38237411e4e202a96b0efe41567505331114bfa8;p=thirdparty%2Fvim.git 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 Signed-off-by: Christian Brabandt --- diff --git a/src/cmdexpand.c b/src/cmdexpand.c index f313981984..19ae319981 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -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; diff --git a/src/fuzzy.c b/src/fuzzy.c index 9a94acea20..bb140fcace 100644 --- a/src/fuzzy.c +++ b/src/fuzzy.c @@ -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++; diff --git a/src/version.c b/src/version.c index 9e794b7ed3..6a8735c6bf 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 476, /**/ 475, /**/