Skip to content

Commit bfa646c

Browse files
committed
Merge branch 'ab/unpack-trees-leakfix'
Leakfix. * ab/unpack-trees-leakfix: sequencer: fix a memory leak in do_reset() sequencer: add a "goto cleanup" to do_reset() unpack-trees: don't leak memory in verify_clean_subdirectory()
2 parents 9101698 + 6e65854 commit bfa646c

File tree

3 files changed

+19
-22
lines changed

3 files changed

+19
-22
lines changed

sequencer.c

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3645,9 +3645,9 @@ static int do_reset(struct repository *r,
36453645
struct strbuf ref_name = STRBUF_INIT;
36463646
struct object_id oid;
36473647
struct lock_file lock = LOCK_INIT;
3648-
struct tree_desc desc;
3648+
struct tree_desc desc = { 0 };
36493649
struct tree *tree;
3650-
struct unpack_trees_options unpack_tree_opts;
3650+
struct unpack_trees_options unpack_tree_opts = { 0 };
36513651
int ret = 0;
36523652

36533653
if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0)
@@ -3679,14 +3679,11 @@ static int do_reset(struct repository *r,
36793679
strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);
36803680
if (get_oid(ref_name.buf, &oid) &&
36813681
get_oid(ref_name.buf + strlen("refs/rewritten/"), &oid)) {
3682-
error(_("could not read '%s'"), ref_name.buf);
3683-
rollback_lock_file(&lock);
3684-
strbuf_release(&ref_name);
3685-
return -1;
3682+
ret = error(_("could not read '%s'"), ref_name.buf);
3683+
goto cleanup;
36863684
}
36873685
}
36883686

3689-
memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
36903687
setup_unpack_trees_porcelain(&unpack_tree_opts, "reset");
36913688
unpack_tree_opts.head_idx = 1;
36923689
unpack_tree_opts.src_index = r->index;
@@ -3698,39 +3695,36 @@ static int do_reset(struct repository *r,
36983695
init_checkout_metadata(&unpack_tree_opts.meta, name, &oid, NULL);
36993696

37003697
if (repo_read_index_unmerged(r)) {
3701-
rollback_lock_file(&lock);
3702-
strbuf_release(&ref_name);
3703-
return error_resolve_conflict(_(action_name(opts)));
3698+
ret = error_resolve_conflict(_(action_name(opts)));
3699+
goto cleanup;
37043700
}
37053701

37063702
if (!fill_tree_descriptor(r, &desc, &oid)) {
3707-
error(_("failed to find tree of %s"), oid_to_hex(&oid));
3708-
rollback_lock_file(&lock);
3709-
free((void *)desc.buffer);
3710-
strbuf_release(&ref_name);
3711-
return -1;
3703+
ret = error(_("failed to find tree of %s"), oid_to_hex(&oid));
3704+
goto cleanup;
37123705
}
37133706

37143707
if (unpack_trees(1, &desc, &unpack_tree_opts)) {
3715-
rollback_lock_file(&lock);
3716-
free((void *)desc.buffer);
3717-
strbuf_release(&ref_name);
3718-
return -1;
3708+
ret = -1;
3709+
goto cleanup;
37193710
}
37203711

37213712
tree = parse_tree_indirect(&oid);
37223713
prime_cache_tree(r, r->index, tree);
37233714

37243715
if (write_locked_index(r->index, &lock, COMMIT_LOCK) < 0)
37253716
ret = error(_("could not write index"));
3726-
free((void *)desc.buffer);
37273717

37283718
if (!ret)
37293719
ret = update_ref(reflog_message(opts, "reset", "'%.*s'",
37303720
len, name), "HEAD", &oid,
37313721
NULL, 0, UPDATE_REFS_MSG_ON_ERR);
3732-
3722+
cleanup:
3723+
free((void *)desc.buffer);
3724+
if (ret < 0)
3725+
rollback_lock_file(&lock);
37333726
strbuf_release(&ref_name);
3727+
clear_unpack_trees_porcelain(&unpack_tree_opts);
37343728
return ret;
37353729
}
37363730

t/t1001-read-tree-m-2way.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ In the test, these paths are used:
2020
rezrov - in H, deleted in M
2121
yomin - not in H or M
2222
'
23+
24+
TEST_PASSES_SANITIZE_LEAK=true
2325
. ./test-lib.sh
2426
. "$TEST_DIRECTORY"/lib-read-tree.sh
2527

unpack-trees.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2156,9 +2156,10 @@ static int verify_clean_subdirectory(const struct cache_entry *ce,
21562156
if (o->dir)
21572157
d.exclude_per_dir = o->dir->exclude_per_dir;
21582158
i = read_directory(&d, o->src_index, pathbuf, namelen+1, NULL);
2159+
dir_clear(&d);
2160+
free(pathbuf);
21592161
if (i)
21602162
return add_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name);
2161-
free(pathbuf);
21622163
return cnt;
21632164
}
21642165

0 commit comments

Comments
 (0)