diff options
| author | Patrick Steinhardt <ps@pks.im> | 2024-09-26 13:46:06 +0200 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2024-09-27 08:25:34 -0700 |
| commit | 3aef7a05adb2868118181eb5605fffa65a9af2c8 (patch) | |
| tree | 25fd341033495e60ba383ad7f327864a60056ccd /git.c | |
| parent | 0f26223b6de6ac3a2e514bb306fef29f34970465 (diff) | |
| download | git-3aef7a05adb2868118181eb5605fffa65a9af2c8.tar.gz | |
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>
Diffstat (limited to 'git.c')
| -rw-r--r-- | git.c | 22 |
1 files changed, 19 insertions, 3 deletions
@@ -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) |
