builtin/annotate: fix leaking args vector

We're leaking the args vector in git-annotate(1) because we never clear it. Fixing it isn't as easy as calling `strvec_clear()` though because calling `cmd_blame()` will cause the underlying array to be modified. Instead, we also need to pass a shallow copy of the argv array to the function. Do so to plug the memory leaks. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Sep 30, 2024 at 11:13 UTC 9a48fc1da277f37b602f48e8bec22f4725ebf877
2 files changed +16 -5
builtin/annotate.c
+15 -5
@@ -15,13 +15,23 @@ int cmd_annotate(int argc,
15 struct repository *repo UNUSED)
16 {
17 struct strvec args = STRVEC_INIT;
18 - int i;
18 + const char **args_copy;
19 + int ret;
20
21 strvec_pushl(&args, "annotate", "-c", NULL);
21 -
22 - for (i = 1; i < argc; i++) {
22 + for (int i = 1; i < argc; i++)
23 strvec_push(&args, argv[i]);
24 - }
24
26 - return cmd_blame(args.nr, args.v, prefix, the_repository);
25 + /*
26 + * `cmd_blame()` ends up modifying the array, which causes memory leaks
27 + * if we didn't copy the array here.
28 + */
29 + CALLOC_ARRAY(args_copy, args.nr + 1);
30 + COPY_ARRAY(args_copy, args.v, args.nr);
31 +
32 + ret = cmd_blame(args.nr, args_copy, prefix, the_repository);
33 +
34 + strvec_clear(&args);
35 + free(args_copy);
36 + return ret;
37 }
t/t8001-annotate.sh
+1
@@ -5,6 +5,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
6
7 TEST_CREATE_REPO_NO_TEMPLATE=1
8 +TEST_PASSES_SANITIZE_LEAK=true
9 . ./test-lib.sh
10
11 PROG='git annotate'