Skip to content

Commit 9748537

Browse files
pks-tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3d31d38 commit 9748537

File tree

4 files changed

+15
-6
lines changed

4 files changed

+15
-6
lines changed

notes.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,12 @@ void init_display_notes(struct display_notes_opt *opt)
10601060
{
10611061
memset(opt, 0, sizeof(*opt));
10621062
opt->use_default_notes = -1;
1063+
string_list_init_dup(&opt->extra_notes_refs);
1064+
}
1065+
1066+
void release_display_notes(struct display_notes_opt *opt)
1067+
{
1068+
string_list_clear(&opt->extra_notes_refs, 0);
10631069
}
10641070

10651071
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,
10731079
struct strbuf buf = STRBUF_INIT;
10741080
strbuf_addstr(&buf, ref);
10751081
expand_notes_ref(&buf);
1076-
string_list_append(&opt->extra_notes_refs,
1077-
strbuf_detach(&buf, NULL));
1082+
string_list_append_nodup(&opt->extra_notes_refs,
1083+
strbuf_detach(&buf, NULL));
10781084
*show_notes = 1;
10791085
}
10801086

10811087
void disable_display_notes(struct display_notes_opt *opt, int *show_notes)
10821088
{
10831089
opt->use_default_notes = -1;
1084-
/* we have been strdup'ing ourselves, so trick
1085-
* string_list into free()ing strings */
1086-
opt->extra_notes_refs.strdup_strings = 1;
10871090
string_list_clear(&opt->extra_notes_refs, 0);
1088-
opt->extra_notes_refs.strdup_strings = 0;
10891091
*show_notes = 0;
10901092
}
10911093

notes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@ struct display_notes_opt {
275275
*/
276276
void init_display_notes(struct display_notes_opt *opt);
277277

278+
/*
279+
* Release resources acquired by the display_notes_opt.
280+
*/
281+
void release_display_notes(struct display_notes_opt *opt);
282+
278283
/*
279284
* This family of functions enables or disables the display of notes. In
280285
* particular, 'enable_default_display_notes' will display the default notes,

revision.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3168,6 +3168,7 @@ void release_revisions(struct rev_info *revs)
31683168
{
31693169
free_commit_list(revs->commits);
31703170
free_commit_list(revs->ancestry_path_bottoms);
3171+
release_display_notes(&revs->notes_opt);
31713172
object_array_clear(&revs->pending);
31723173
object_array_clear(&revs->boundary_commits);
31733174
release_revisions_cmdline(&revs->cmdline);

t/t3301-notes.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
test_description='Test commit notes'
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910

1011
write_script fake_editor <<\EOF

0 commit comments

Comments
 (0)