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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Nov 20, 2024 at 14:39 UTC
c1e98f90103e8d98ef441ce8f609cf3bc8fa538b
2 files changed
+23
-8
bisect.c
+22
-8
@@ -442,9 +442,12 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
442
best->next = NULL;
443
}
444
*reaches = weight(best);
445
+ } else {
446
+ free_commit_list(*commit_list);
447
}
446
- free(weights);
448
*commit_list = best;
449
+
450
+ free(weights);
451
clear_commit_weight(&commit_weight);
452
}
453
@@ -557,8 +560,11 @@ struct commit_list *filter_skipped(struct commit_list *list,
560
tried = &list->next;
561
} else {
562
if (!show_all) {
560
- if (!skipped_first || !*skipped_first)
563
+ if (!skipped_first || !*skipped_first) {
564
+ free_commit_list(next);
565
+ free_commit_list(filtered);
566
return list;
567
+ }
568
} else if (skipped_first && !*skipped_first) {
569
/* This means we know it's not skipped */
570
*skipped_first = -1;
@@ -614,7 +620,7 @@ static int sqrti(int val)
620
621
static struct commit_list *skip_away(struct commit_list *list, int count)
622
{
617
- struct commit_list *cur, *previous;
623
+ struct commit_list *cur, *previous, *result = list;
624
int prn, index, i;
625
626
prn = get_prn(count);
@@ -626,15 +632,23 @@ static struct commit_list *skip_away(struct commit_list *list, int count)
632
for (i = 0; cur; cur = cur->next, i++) {
633
if (i == index) {
634
if (!oideq(&cur->item->object.oid, current_bad_oid))
629
- return cur;
630
- if (previous)
631
- return previous;
632
- return list;
635
+ result = cur;
636
+ else if (previous)
637
+ result = previous;
638
+ else
639
+ result = list;
640
+ break;
641
}
642
previous = cur;
643
}
644
637
- return list;
645
+ for (cur = list; cur != result; ) {
646
+ struct commit_list *next = cur->next;
647
+ free(cur);
648
+ cur = next;
649
+ }
650
+
651
+ return result;
652
}
653
654
static struct commit_list *managed_skipped(struct commit_list *list,
t/t6030-bisect-porcelain.sh
+1
@@ -9,6 +9,7 @@ exec </dev/null
9
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
10
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
11
12
+TEST_PASSES_SANITIZE_LEAK=true
13
. ./test-lib.sh
14
15
add_line_into_file()