aboutsummaryrefslogtreecommitdiffstats
path: root/bisect.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2024-11-20 14:39:36 +0100
committerJunio C Hamano <gitster@pobox.com>2024-11-21 08:23:42 +0900
commitc1e98f90103e8d98ef441ce8f609cf3bc8fa538b (patch)
tree97b4284234d8ed49bb2cf41ec757cbbaf1a46c9b /bisect.c
parentbisect: fix leaking commit list items in `check_merge_base()` (diff)
downloadgit-c1e98f90103e8d98ef441ce8f609cf3bc8fa538b.tar.gz
git-c1e98f90103e8d98ef441ce8f609cf3bc8fa538b.zip
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>
Diffstat (limited to 'bisect.c')
-rw-r--r--bisect.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/bisect.c b/bisect.c
index 12efcff2e3..f6fa5c235f 100644
--- a/bisect.c
+++ b/bisect.c
@@ -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,