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@xxxxxx> --- bisect.c | 35 +++++++++++++++++++++++++++-------- t/t6030-bisect-porcelain.sh | 1 + 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/bisect.c b/bisect.c index 12efcff2e3c..518be70aa3f 100644 --- a/bisect.c +++ b/bisect.c @@ -440,11 +440,19 @@ void find_bisection(struct commit_list **commit_list, int *reaches, free_commit_list(list->next); best = list; best->next = NULL; + } else { + for (p = list; p != best; p = next) { + next = p->next; + free(p); + } } *reaches = weight(best); + } else { + free_commit_list(*commit_list); } - free(weights); *commit_list = best; + + free(weights); clear_commit_weight(&commit_weight); } @@ -557,8 +565,11 @@ struct commit_list *filter_skipped(struct commit_list *list, tried = &list->next; } else { if (!show_all) { - if (!skipped_first || !*skipped_first) + if (!skipped_first || !*skipped_first) { + free_commit_list(next); + free_commit_list(filtered); return list; + } } else if (skipped_first && !*skipped_first) { /* This means we know it's not skipped */ *skipped_first = -1; @@ -614,7 +625,7 @@ static int sqrti(int val) static struct commit_list *skip_away(struct commit_list *list, int count) { - struct commit_list *cur, *previous; + struct commit_list *cur, *previous, *result = list; int prn, index, i; prn = get_prn(count); @@ -626,15 +637,23 @@ static struct commit_list *skip_away(struct commit_list *list, int count) for (i = 0; cur; cur = cur->next, i++) { if (i == index) { if (!oideq(&cur->item->object.oid, current_bad_oid)) - return cur; - if (previous) - return previous; - return list; + result = cur; + else if (previous) + result = previous; + else + result = list; + break; } previous = cur; } - return list; + for (cur = list; cur != result; ) { + struct commit_list *next = cur->next; + free(cur); + cur = next; + } + + return result; } static struct commit_list *managed_skipped(struct commit_list *list, diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index cdc02706404..310affadebe 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -9,6 +9,7 @@ exec </dev/null GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh add_line_into_file() -- 2.47.0.229.g8f8d6eee53.dirty