The strings allocated in `setup_unpack_trees_porcelain()` are never freed. Provide a function `clear_unpack_trees_porcelain()` to do so and call it in the functions which use `setup_unpack_trees_porcelain()`. In all current callers, the pointers are about to go out of scope, so we do not need to set them to NULL. Let's do so anyway so that a future caller or restructured code doesn't suddenly start accessing dangling pointers. Note that we only take responsibility for the memory allocated in `setup_unpack_trees_porcelain()` and not any other members of the `struct unpack_trees_options`. Signed-off-by: Martin Ågren <martin.agren@xxxxxxxxx> --- unpack-trees.h | 5 +++++ builtin/checkout.c | 1 + merge-recursive.c | 1 + merge.c | 3 +++ unpack-trees.c | 11 +++++++++++ 5 files changed, 21 insertions(+) diff --git a/unpack-trees.h b/unpack-trees.h index 6c48117b84..8c56cf0150 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -32,6 +32,11 @@ enum unpack_trees_error_types { void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, const char *cmd); +/* + * Frees resources allocated by setup_unpack_trees_porcelain(). + */ +extern void clear_unpack_trees_porcelain(struct unpack_trees_options *opts); + struct unpack_trees_options { unsigned int reset, merge, diff --git a/builtin/checkout.c b/builtin/checkout.c index b49b582071..5cebe170fc 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -526,6 +526,7 @@ static int merge_working_tree(const struct checkout_opts *opts, init_tree_desc(&trees[1], tree->buffer, tree->size); ret = unpack_trees(2, trees, &topts); + clear_unpack_trees_porcelain(&topts); if (ret == -1) { /* * Unpack couldn't do a trivial merge; either diff --git a/merge-recursive.c b/merge-recursive.c index 0c0d48624d..8229b91e2f 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -301,6 +301,7 @@ static int git_merge_trees(int index_only, init_tree_desc_from_tree(t+2, merge); rc = unpack_trees(3, t, &opts); + clear_unpack_trees_porcelain(&opts); cache_tree_free(&active_cache_tree); return rc; } diff --git a/merge.c b/merge.c index f123658e58..b433291d0c 100644 --- a/merge.c +++ b/merge.c @@ -130,8 +130,11 @@ int checkout_fast_forward(const struct object_id *head, if (unpack_trees(nr_trees, t, &opts)) { rollback_lock_file(&lock_file); + clear_unpack_trees_porcelain(&opts); return -1; } + clear_unpack_trees_porcelain(&opts); + if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) return error(_("unable to write new index file")); return 0; diff --git a/unpack-trees.c b/unpack-trees.c index e73745051e..4c76a29241 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -179,6 +179,17 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, opts->unpack_rejects[i].strdup_strings = 1; } +void clear_unpack_trees_porcelain(struct unpack_trees_options *opts) +{ + char **msgs = (char **)opts->msgs; + + free(msgs[ERROR_WOULD_OVERWRITE]); + free(msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED]); + free(msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN]); + + memset(opts->msgs, 0, sizeof(opts->msgs)); +} + static int do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce, unsigned int set, unsigned int clear) { -- 2.17.0