]> git.ipfire.org Git - thirdparty/git.git/commitdiff
bisect: fix various cases where we leak commit list items
authorPatrick Steinhardt <ps@pks.im>
Wed, 20 Nov 2024 13:39:36 +0000 (14:39 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Nov 2024 23:23:42 +0000 (08:23 +0900)
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>
bisect.c
t/t6030-bisect-porcelain.sh

index 12efcff2e3c1836ab6e63d36e4d42269fbcaeaab..f6fa5c235ffb351011ed5e81771fbcdad9ca0917 100644 (file)
--- 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,
index cdc02706404b34b17b29692d72d97fab7eba58b1..310affadebed321fcc93ee5bd785abf4ca013cc1 100755 (executable)
@@ -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()