Skip to content

Commit 3199b22

Browse files
pks-tgitster
authored andcommitted
builtin/merge-recursive: fix leaking object ID bases
In `cmd_merge_recursive()` we have a static array of object ID bases that we pass to `merge_recursive_generic()`. This interface is somewhat weird though because the latter function accepts a pointer to a pointer of object IDs, which requires us to allocate the object IDs on the heap. And as we never free those object IDs, the end result is a leak. While we can easily solve this leak by just freeing the respective object IDs, the whole calling convention is somewhat weird. Instead, refactor `merge_recursive_generic()` to accept a plain pointer to object IDs so that we can avoid allocating them altogether. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9e903a5 commit 3199b22

File tree

6 files changed

+12
-12
lines changed

6 files changed

+12
-12
lines changed

builtin/am.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,8 +1573,8 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
15731573
*/
15741574
static int fall_back_threeway(const struct am_state *state, const char *index_path)
15751575
{
1576-
struct object_id orig_tree, their_tree, our_tree;
1577-
const struct object_id *bases[1] = { &orig_tree };
1576+
struct object_id their_tree, our_tree;
1577+
struct object_id bases[1] = { 0 };
15781578
struct merge_options o;
15791579
struct commit *result;
15801580
char *their_tree_name;
@@ -1588,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
15881588
discard_index(the_repository->index);
15891589
read_index_from(the_repository->index, index_path, get_git_dir());
15901590

1591-
if (write_index_as_tree(&orig_tree, the_repository->index, index_path, 0, NULL))
1591+
if (write_index_as_tree(&bases[0], the_repository->index, index_path, 0, NULL))
15921592
return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));
15931593

15941594
say(state, stdout, _("Using index info to reconstruct a base tree..."));

builtin/merge-recursive.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ static char *better_branch_name(const char *branch)
2323

2424
int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
2525
{
26-
const struct object_id *bases[21];
26+
struct object_id bases[21];
2727
unsigned bases_count = 0;
2828
int i, failed;
2929
struct object_id h1, h2;
@@ -49,10 +49,8 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
4949
continue;
5050
}
5151
if (bases_count < ARRAY_SIZE(bases)-1) {
52-
struct object_id *oid = xmalloc(sizeof(struct object_id));
53-
if (repo_get_oid(the_repository, argv[i], oid))
52+
if (repo_get_oid(the_repository, argv[i], &bases[bases_count++]))
5453
die(_("could not parse object '%s'"), argv[i]);
55-
bases[bases_count++] = oid;
5654
}
5755
else
5856
warning(Q_("cannot handle more than %d base. "

merge-recursive.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,7 +3866,7 @@ int merge_recursive_generic(struct merge_options *opt,
38663866
const struct object_id *head,
38673867
const struct object_id *merge,
38683868
int num_merge_bases,
3869-
const struct object_id **merge_bases,
3869+
const struct object_id *merge_bases,
38703870
struct commit **result)
38713871
{
38723872
int clean;
@@ -3879,10 +3879,10 @@ int merge_recursive_generic(struct merge_options *opt,
38793879
int i;
38803880
for (i = 0; i < num_merge_bases; ++i) {
38813881
struct commit *base;
3882-
if (!(base = get_ref(opt->repo, merge_bases[i],
3883-
oid_to_hex(merge_bases[i]))))
3882+
if (!(base = get_ref(opt->repo, &merge_bases[i],
3883+
oid_to_hex(&merge_bases[i]))))
38843884
return err(opt, _("Could not parse object '%s'"),
3885-
oid_to_hex(merge_bases[i]));
3885+
oid_to_hex(&merge_bases[i]));
38863886
commit_list_insert(base, &ca);
38873887
}
38883888
if (num_merge_bases == 1)

merge-recursive.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ int merge_recursive_generic(struct merge_options *opt,
123123
const struct object_id *head,
124124
const struct object_id *merge,
125125
int num_merge_bases,
126-
const struct object_id **merge_bases,
126+
const struct object_id *merge_bases,
127127
struct commit **result);
128128

129129
#endif

t/t6432-merge-recursive-space-options.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ test_description='merge-recursive space options
1414
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
1515
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1616

17+
TEST_PASSES_SANITIZE_LEAK=true
1718
. ./test-lib.sh
1819

1920
test_have_prereq SED_STRIPS_CR && SED_OPTIONS=-b

t/t6434-merge-recursive-rename-options.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mentions this in a different context).
2929
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
3030
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
3131

32+
TEST_PASSES_SANITIZE_LEAK=true
3233
. ./test-lib.sh
3334

3435
get_expected_stages () {

0 commit comments

Comments
 (0)