Skip to content

Commit 616f295

Browse files
pks-tgitster
authored andcommitted
bisect: fix various cases where we leak commit list items
There are various cases where we leak commit list items because we evict items from the list, but don't free them. Plug those. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4f3fddf commit 616f295

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

bisect.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -440,11 +440,19 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
440440
free_commit_list(list->next);
441441
best = list;
442442
best->next = NULL;
443+
} else {
444+
for (p = list; p != best; p = next) {
445+
next = p->next;
446+
free(p);
447+
}
443448
}
444449
*reaches = weight(best);
450+
} else {
451+
free_commit_list(*commit_list);
445452
}
446-
free(weights);
447453
*commit_list = best;
454+
455+
free(weights);
448456
clear_commit_weight(&commit_weight);
449457
}
450458

@@ -557,8 +565,11 @@ struct commit_list *filter_skipped(struct commit_list *list,
557565
tried = &list->next;
558566
} else {
559567
if (!show_all) {
560-
if (!skipped_first || !*skipped_first)
568+
if (!skipped_first || !*skipped_first) {
569+
free_commit_list(next);
570+
free_commit_list(filtered);
561571
return list;
572+
}
562573
} else if (skipped_first && !*skipped_first) {
563574
/* This means we know it's not skipped */
564575
*skipped_first = -1;
@@ -614,7 +625,7 @@ static int sqrti(int val)
614625

615626
static struct commit_list *skip_away(struct commit_list *list, int count)
616627
{
617-
struct commit_list *cur, *previous;
628+
struct commit_list *cur, *previous, *result = list;
618629
int prn, index, i;
619630

620631
prn = get_prn(count);
@@ -626,15 +637,23 @@ static struct commit_list *skip_away(struct commit_list *list, int count)
626637
for (i = 0; cur; cur = cur->next, i++) {
627638
if (i == index) {
628639
if (!oideq(&cur->item->object.oid, current_bad_oid))
629-
return cur;
630-
if (previous)
631-
return previous;
632-
return list;
640+
result = cur;
641+
else if (previous)
642+
result = previous;
643+
else
644+
result = list;
645+
break;
633646
}
634647
previous = cur;
635648
}
636649

637-
return list;
650+
for (cur = list; cur != result; ) {
651+
struct commit_list *next = cur->next;
652+
free(cur);
653+
cur = next;
654+
}
655+
656+
return result;
638657
}
639658

640659
static struct commit_list *managed_skipped(struct commit_list *list,

t/t6030-bisect-porcelain.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ exec </dev/null
99
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
1010
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1111

12+
TEST_PASSES_SANITIZE_LEAK=true
1213
. ./test-lib.sh
1314

1415
add_line_into_file()

0 commit comments

Comments
 (0)