git: fix leaking argv when handling builtins

In `handle_builtin()` we may end up creating an ad-hoc argv array in
case we see that the command line contains the "--help" parameter. In
this case we observe two memory leaks though:

  - We leak the `struct strvec` itself because we directly exit after
    calling `run_builtin()`, without bothering about any cleanups.

  - Even if we free'd that vector we'd end up leaking some of its
    strings because `run_builtin()` will modify the array.

Plug both of these leaks.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2024-09-26 13:46:06 +02:00
committed by Junio C Hamano
parent 0f26223b6d
commit 3aef7a05ad
2 changed files with 20 additions and 3 deletions

22
git.c
View File

@ -711,6 +711,7 @@ static void strip_extension(const char **argv)
static void handle_builtin(int argc, const char **argv)
{
struct strvec args = STRVEC_INIT;
const char **argv_copy = NULL;
const char *cmd;
struct cmd_struct *builtin;
@ -731,13 +732,28 @@ static void handle_builtin(int argc, const char **argv)
}
argc++;
argv = args.v;
/*
* `run_builtin()` will modify the argv array, so we need to
* create a shallow copy such that we can free all of its
* strings.
*/
CALLOC_ARRAY(argv_copy, argc + 1);
COPY_ARRAY(argv_copy, args.v, argc);
argv = argv_copy;
}
builtin = get_builtin(cmd);
if (builtin)
exit(run_builtin(builtin, argc, argv));
if (builtin) {
int ret = run_builtin(builtin, argc, argv);
strvec_clear(&args);
free(argv_copy);
exit(ret);
}
strvec_clear(&args);
free(argv_copy);
}
static void execv_dashed_external(const char **argv)