]> git.ipfire.org Git - thirdparty/git.git/commitdiff
grep: fix a "path_list" memory leak
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Fri, 22 Oct 2021 08:55:41 +0000 (10:55 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sat, 23 Oct 2021 17:45:25 +0000 (10:45 -0700)
Free the "path_list" used in builtin/grep.c, it was declared as
STRING_LIST_INIT_NODUP, let's change it to a STRING_LIST_INIT_DUP
since an early user in cmd_grep() appends a string passed via
parse-options.c to it, which needs to be duplicated.

Let's then convert the remaining callers to use
string_list_append_nodup() instead, allowing us to free the list.

This makes all the tests in t7811-grep-open.sh pass, 6/10 would fail
before this change. The only remaining failure would have been due to
a stray "git checkout" (which still leaks memory). In this case we can
use a "git reset --hard" instead, so let's do that, and move the
test_when_finished() above the code that would modify the relevant
file.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/grep.c
t/t7811-grep-open.sh

index 555b2ab6008fb3a6c095c4c3317f364619b6e503..9e34a820ad4d837937a0ecb2bc712de972506b50 100644 (file)
@@ -401,7 +401,7 @@ static void append_path(struct grep_opt *opt, const void *data, size_t len)
 
        if (len == 1 && *(const char *)data == '\0')
                return;
-       string_list_append(path_list, xstrndup(data, len));
+       string_list_append_nodup(path_list, xstrndup(data, len));
 }
 
 static void run_pager(struct grep_opt *opt, const char *prefix)
@@ -839,7 +839,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
        struct grep_opt opt;
        struct object_array list = OBJECT_ARRAY_INIT;
        struct pathspec pathspec;
-       struct string_list path_list = STRING_LIST_INIT_NODUP;
+       struct string_list path_list = STRING_LIST_INIT_DUP;
        int i;
        int dummy;
        int use_index = 1;
@@ -1159,8 +1159,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                        strbuf_addf(&buf, "+/%s%s",
                                        strcmp("less", pager) ? "" : "*",
                                        opt.pattern_list->pattern);
-                       string_list_append(&path_list,
-                                          strbuf_detach(&buf, NULL));
+                       string_list_append_nodup(&path_list,
+                                                strbuf_detach(&buf, NULL));
                }
        }
 
@@ -1195,6 +1195,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
        if (hit && show_in_pager)
                run_pager(&opt, prefix);
        clear_pathspec(&pathspec);
+       string_list_clear(&path_list, 0);
        free_grep_patterns(&opt);
        object_array_clear(&list);
        free_repos();
index a98785da7955b6cc41fe5aedc6f339311e3f989e..1dd07141a7df9f9666ac01a611c6c6a81ddc6424 100755 (executable)
@@ -3,6 +3,7 @@
 test_description='git grep --open-files-in-pager
 '
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-pager.sh
 unset PAGER GIT_PAGER
@@ -114,8 +115,8 @@ test_expect_success 'modified file' '
        unrelated
        EOF
 
+       test_when_finished "git reset --hard" &&
        echo "enum grep_pat_token" >unrelated &&
-       test_when_finished "git checkout HEAD unrelated" &&
        GIT_PAGER=./less git grep -F -O "enum grep_pat_token" >out &&
        test_cmp expect actual &&
        test_must_be_empty out