@@ -442,9 +442,12 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
best->next = NULL;
}
*reaches = weight(best);
+ } else {
+ free_commit_list(*commit_list);
}
- free(weights);
*commit_list = best;
+
+ free(weights);
clear_commit_weight(&commit_weight);
}
@@ -557,8 +560,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 +620,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 +632,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,
@@ -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()
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> --- bisect.c | 30 ++++++++++++++++++++++-------- t/t6030-bisect-porcelain.sh | 1 + 2 files changed, 23 insertions(+), 8 deletions(-)