From 97485374377fa62fdd36f4b707e2fcd8f1a7c6c3 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Jun 2024 11:19:45 +0200 Subject: revision: fix leaking display notes We never free the display notes options embedded into `struct revision`. Implement a new function `release_display_notes()` that we can call in `release_revisions()` to fix this. There is another gotcha here though: we play some games with the string list used to track extra notes refs, where we sometimes set the bit that indicates that strings should be strdup'd and sometimes unset it. This dance is done to avoid a copy of an already-allocated string when we call `enable_ref_display_notes()`. But this dance is rather pointless as we can instead call `string_list_append_nodup()` to transfer ownership of the allocated string to the list. Refactor the code to do so and drop the `strdup_strings` dance. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- notes.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'notes.c') diff --git a/notes.c b/notes.c index 53ca25c814..6a157e34ce 100644 --- a/notes.c +++ b/notes.c @@ -1060,6 +1060,12 @@ void init_display_notes(struct display_notes_opt *opt) { memset(opt, 0, sizeof(*opt)); opt->use_default_notes = -1; + string_list_init_dup(&opt->extra_notes_refs); +} + +void release_display_notes(struct display_notes_opt *opt) +{ + string_list_clear(&opt->extra_notes_refs, 0); } void enable_default_display_notes(struct display_notes_opt *opt, int *show_notes) @@ -1073,19 +1079,15 @@ void enable_ref_display_notes(struct display_notes_opt *opt, int *show_notes, struct strbuf buf = STRBUF_INIT; strbuf_addstr(&buf, ref); expand_notes_ref(&buf); - string_list_append(&opt->extra_notes_refs, - strbuf_detach(&buf, NULL)); + string_list_append_nodup(&opt->extra_notes_refs, + strbuf_detach(&buf, NULL)); *show_notes = 1; } void disable_display_notes(struct display_notes_opt *opt, int *show_notes) { opt->use_default_notes = -1; - /* we have been strdup'ing ourselves, so trick - * string_list into free()ing strings */ - opt->extra_notes_refs.strdup_strings = 1; string_list_clear(&opt->extra_notes_refs, 0); - opt->extra_notes_refs.strdup_strings = 0; *show_notes = 0; } -- cgit v1.3 From f644dc84949bcc6d6d06274a30feb4b366ae68de Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Jun 2024 11:19:50 +0200 Subject: notes: fix memory leak when pruning notes In `prune_notes()` we first store the notes that are to be deleted in a local list, and then iterate through that list to delete those notes one by one. We never free the list though and thus leak its memory. Fix this. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- notes.c | 7 ++++++- t/t3306-notes-prune.sh | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'notes.c') diff --git a/notes.c b/notes.c index 6a157e34ce..244b5c4b1c 100644 --- a/notes.c +++ b/notes.c @@ -1219,11 +1219,16 @@ void prune_notes(struct notes_tree *t, int flags) for_each_note(t, 0, prune_notes_helper, &l); while (l) { + struct note_delete_list *next; + if (flags & NOTES_PRUNE_VERBOSE) printf("%s\n", hash_to_hex(l->sha1)); if (!(flags & NOTES_PRUNE_DRYRUN)) remove_note(t, l->sha1); - l = l->next; + + next = l->next; + free(l); + l = next; } } diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh index 8f4102ff9e..b6e9f643e3 100755 --- a/t/t3306-notes-prune.sh +++ b/t/t3306-notes-prune.sh @@ -2,6 +2,7 @@ test_description='Test git notes prune' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: create a few commits with notes' ' -- cgit v1.3