summaryrefslogtreecommitdiffstats
path: root/git.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2024-10-02 16:46:25 +0200
committerJunio C Hamano <gitster@pobox.com>2024-10-02 16:46:26 +0200
commit365529e1ea19b44a7a253b780f3ae3a1cb2f081f (patch)
tree5a34837f74d165858246b1dd9706b926d7a998e5 /git.c
parentMerge branch 'ds/sparse-checkout-expansion-advice' (diff)
parentdiffcore-break: fix leaking filespecs when merging broken pairs (diff)
downloadgit-365529e1ea19b44a7a253b780f3ae3a1cb2f081f.tar.xz
git-365529e1ea19b44a7a253b780f3ae3a1cb2f081f.zip
Merge branch 'ps/leakfixes-part-7'
More leak-fixes. * ps/leakfixes-part-7: (23 commits) diffcore-break: fix leaking filespecs when merging broken pairs revision: fix leaking parents when simplifying commits builtin/maintenance: fix leak in `get_schedule_cmd()` builtin/maintenance: fix leaking config string promisor-remote: fix leaking partial clone filter grep: fix leaking grep pattern submodule: fix leaking submodule ODB paths trace2: destroy context stored in thread-local storage builtin/difftool: plug several trivial memory leaks builtin/repack: fix leaking configuration diffcore-order: fix leaking buffer when parsing orderfiles parse-options: free previous value of `OPTION_FILENAME` diff: fix leaking orderfile option builtin/pull: fix leaking "ff" option dir: fix off by one errors for ignored and untracked entries builtin/submodule--helper: fix leaking remote ref on errors t/helper: fix leaking subrepo in nested submodule config helper builtin/submodule--helper: fix leaking error buffer builtin/submodule--helper: clear child process when not running it submodule: fix leaking update strategy ...
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 2fbea24ec9..2a9752c91c 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, the_repository));
+ if (builtin) {
+ int ret = run_builtin(builtin, argc, argv, the_repository);
+ strvec_clear(&args);
+ free(argv_copy);
+ exit(ret);
+ }
+
strvec_clear(&args);
+ free(argv_copy);
}
static void execv_dashed_external(const char **argv)