aboutsummaryrefslogtreecommitdiffstats
path: root/git.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2024-09-26 13:46:06 +0200
committerJunio C Hamano <gitster@pobox.com>2024-09-27 08:25:34 -0700
commit3aef7a05adb2868118181eb5605fffa65a9af2c8 (patch)
tree25fd341033495e60ba383ad7f327864a60056ccd /git.c
parent0f26223b6de6ac3a2e514bb306fef29f34970465 (diff)
downloadgit-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.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/git.c b/git.c
index 9a618a2740..3c7fabfda2 100644
--- a/git.c
+++ b/git.c
@@ -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)