Skip to content

Commit 11d6a81

Browse files
pks-tgitster
authored andcommitted
builtin/show-branch: fix several memory leaks
There are several memory leaks in git-show-branch(1). Fix them. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2d197e4 commit 11d6a81

File tree

3 files changed

+38
-16
lines changed

3 files changed

+38
-16
lines changed

builtin/show-branch.c

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -502,14 +502,14 @@ static int rev_is_head(const char *head, const char *name)
502502
return !strcmp(head, name);
503503
}
504504

505-
static int show_merge_base(struct commit_list *seen, int num_rev)
505+
static int show_merge_base(const struct commit_list *seen, int num_rev)
506506
{
507507
int all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
508508
int all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
509509
int exit_status = 1;
510510

511-
while (seen) {
512-
struct commit *commit = pop_commit(&seen);
511+
for (const struct commit_list *s = seen; s; s = s->next) {
512+
struct commit *commit = s->item;
513513
int flags = commit->object.flags & all_mask;
514514
if (!(flags & UNINTERESTING) &&
515515
((flags & all_revs) == all_revs)) {
@@ -635,7 +635,7 @@ static int parse_reflog_param(const struct option *opt, const char *arg,
635635
int cmd_show_branch(int ac, const char **av, const char *prefix)
636636
{
637637
struct commit *rev[MAX_REVS], *commit;
638-
char *reflog_msg[MAX_REVS];
638+
char *reflog_msg[MAX_REVS] = {0};
639639
struct commit_list *list = NULL, *seen = NULL;
640640
unsigned int rev_mask[MAX_REVS];
641641
int num_rev, i, extra = 0;
@@ -692,15 +692,18 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
692692
parse_reflog_param),
693693
OPT_END()
694694
};
695+
const char **args_copy = NULL;
696+
int ret;
695697

696698
init_commit_name_slab(&name_slab);
697699

698700
git_config(git_show_branch_config, NULL);
699701

700702
/* If nothing is specified, try the default first */
701703
if (ac == 1 && default_args.nr) {
704+
DUP_ARRAY(args_copy, default_args.v, default_args.nr);
702705
ac = default_args.nr;
703-
av = default_args.v;
706+
av = args_copy;
704707
}
705708

706709
ac = parse_options(ac, av, prefix, builtin_show_branch_options,
@@ -780,7 +783,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
780783
}
781784

782785
for (i = 0; i < reflog; i++) {
783-
char *logmsg;
786+
char *logmsg = NULL;
784787
char *nth_desc;
785788
const char *msg;
786789
char *end;
@@ -790,6 +793,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
790793
if (read_ref_at(get_main_ref_store(the_repository),
791794
ref, flags, 0, base + i, &oid, &logmsg,
792795
&timestamp, &tz, NULL)) {
796+
free(logmsg);
793797
reflog = i;
794798
break;
795799
}
@@ -842,7 +846,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
842846

843847
if (!ref_name_cnt) {
844848
fprintf(stderr, "No revs to be shown.\n");
845-
exit(0);
849+
ret = 0;
850+
goto out;
846851
}
847852

848853
for (num_rev = 0; ref_name[num_rev]; num_rev++) {
@@ -879,11 +884,15 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
879884

880885
commit_list_sort_by_date(&seen);
881886

882-
if (merge_base)
883-
return show_merge_base(seen, num_rev);
887+
if (merge_base) {
888+
ret = show_merge_base(seen, num_rev);
889+
goto out;
890+
}
884891

885-
if (independent)
886-
return show_independent(rev, num_rev, rev_mask);
892+
if (independent) {
893+
ret = show_independent(rev, num_rev, rev_mask);
894+
goto out;
895+
}
887896

888897
/* Show list; --more=-1 means list-only */
889898
if (1 < num_rev || extra < 0) {
@@ -919,8 +928,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
919928
putchar('\n');
920929
}
921930
}
922-
if (extra < 0)
923-
exit(0);
931+
if (extra < 0) {
932+
ret = 0;
933+
goto out;
934+
}
924935

925936
/* Sort topologically */
926937
sort_in_topological_order(&seen, sort_order);
@@ -932,8 +943,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
932943
all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
933944
all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
934945

935-
while (seen) {
936-
struct commit *commit = pop_commit(&seen);
946+
for (struct commit_list *l = seen; l; l = l->next) {
947+
struct commit *commit = l->item;
937948
int this_flag = commit->object.flags;
938949
int is_merge_point = ((this_flag & all_revs) == all_revs);
939950

@@ -973,6 +984,15 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
973984
if (shown_merge_point && --extra < 0)
974985
break;
975986
}
987+
988+
ret = 0;
989+
990+
out:
991+
for (size_t i = 0; i < ARRAY_SIZE(reflog_msg); i++)
992+
free(reflog_msg[i]);
993+
free_commit_list(seen);
994+
free_commit_list(list);
995+
free(args_copy);
976996
free(head);
977-
return 0;
997+
return ret;
978998
}

t/t3202-show-branch.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
test_description='test show-branch'
44

5+
TEST_PASSES_SANITIZE_LEAK=true
56
. ./test-lib.sh
67

78
test_expect_success 'error descriptions on empty repository' '

t/t6010-merge-base.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
test_description='Merge base and parent list computation.
77
'
88

9+
TEST_PASSES_SANITIZE_LEAK=true
910
. ./test-lib.sh
1011

1112
M=1130000000

0 commit comments

Comments
 (0)