Git fork

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>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
c1e98f90 2b7706aa

+23 -8
+22 -8
bisect.c
··· 442 best->next = NULL; 443 } 444 *reaches = weight(best); 445 } 446 free(weights); 447 - *commit_list = best; 448 clear_commit_weight(&commit_weight); 449 } 450 ··· 557 tried = &list->next; 558 } else { 559 if (!show_all) { 560 - if (!skipped_first || !*skipped_first) 561 return list; 562 } else if (skipped_first && !*skipped_first) { 563 /* This means we know it's not skipped */ 564 *skipped_first = -1; ··· 614 615 static struct commit_list *skip_away(struct commit_list *list, int count) 616 { 617 - struct commit_list *cur, *previous; 618 int prn, index, i; 619 620 prn = get_prn(count); ··· 626 for (i = 0; cur; cur = cur->next, i++) { 627 if (i == index) { 628 if (!oideq(&cur->item->object.oid, current_bad_oid)) 629 - return cur; 630 - if (previous) 631 - return previous; 632 - return list; 633 } 634 previous = cur; 635 } 636 637 - return list; 638 } 639 640 static struct commit_list *managed_skipped(struct commit_list *list,
··· 442 best->next = NULL; 443 } 444 *reaches = weight(best); 445 + } else { 446 + free_commit_list(*commit_list); 447 } 448 + *commit_list = best; 449 + 450 free(weights); 451 clear_commit_weight(&commit_weight); 452 } 453 ··· 560 tried = &list->next; 561 } else { 562 if (!show_all) { 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; ··· 620 621 static struct commit_list *skip_away(struct commit_list *list, int count) 622 { 623 + struct commit_list *cur, *previous, *result = list; 624 int prn, index, i; 625 626 prn = get_prn(count); ··· 632 for (i = 0; cur; cur = cur->next, i++) { 633 if (i == index) { 634 if (!oideq(&cur->item->object.oid, current_bad_oid)) 635 + result = cur; 636 + else if (previous) 637 + result = previous; 638 + else 639 + result = list; 640 + break; 641 } 642 previous = cur; 643 } 644 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,
+1
t/t6030-bisect-porcelain.sh
··· 9 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 10 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 11 12 . ./test-lib.sh 13 14 add_line_into_file()
··· 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()