commit-graph: fix memory leak in misused string_list API

When this code was migrated to the string_list API in d88b14b3fd6 (commit-graph: use string-list API for input, 2018-06-27) it was made to use used both STRING_LIST_INIT_NODUP and a strbuf_detach() pattern. Those should not be used together if string_list_clear() is expected to free the memory, instead we need to either use STRING_LIST_INIT_DUP with a string_list_append_nodup(), or a STRING_LIST_INIT_NODUP and manually fiddle with the "strdup_strings" member before calling string_list_clear(). Let's do the former. Since "strdup_strings = 1" is set now other code might be broken by relying on "pack_indexes" not to duplicate it strings, but that doesn't happen. When we pass this down to write_commit_graph() that code uses the "struct string_list" without modifying it. Let's add a "const" to the variable to have the compiler enforce that assumption. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Mar 4, 2022 at 19:32 UTC 4a0479086a9bea5d31c4588b07bd45ae92a12b71
3 files changed +6 -6
builtin/commit-graph.c
+3 -3
@@ -192,7 +192,7 @@ static int git_commit_graph_write_config(const char *var, const char *value,
192
193 static int graph_write(int argc, const char **argv)
194 {
195 - struct string_list pack_indexes = STRING_LIST_INIT_NODUP;
195 + struct string_list pack_indexes = STRING_LIST_INIT_DUP;
196 struct strbuf buf = STRBUF_INIT;
197 struct oidset commits = OIDSET_INIT;
198 struct object_directory *odb = NULL;
@@ -273,8 +273,8 @@ static int graph_write(int argc, const char **argv)
273
274 if (opts.stdin_packs) {
275 while (strbuf_getline(&buf, stdin) != EOF)
276 - string_list_append(&pack_indexes,
277 - strbuf_detach(&buf, NULL));
276 + string_list_append_nodup(&pack_indexes,
277 + strbuf_detach(&buf, NULL));
278 } else if (opts.stdin_commits) {
279 oidset_init(&commits, 0);
280 if (opts.progress)
commit-graph.c
+2 -2
@@ -1679,7 +1679,7 @@ int write_commit_graph_reachable(struct object_directory *odb,
1679 }
1680
1681 static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
1682 - struct string_list *pack_indexes)
1682 + const struct string_list *pack_indexes)
1683 {
1684 uint32_t i;
1685 struct strbuf progress_title = STRBUF_INIT;
@@ -2259,7 +2259,7 @@ out:
2259 }
2260
2261 int write_commit_graph(struct object_directory *odb,
2262 - struct string_list *pack_indexes,
2262 + const struct string_list *const pack_indexes,
2263 struct oidset *commits,
2264 enum commit_graph_write_flags flags,
2265 const struct commit_graph_opts *opts)
commit-graph.h
+1 -1
@@ -142,7 +142,7 @@ int write_commit_graph_reachable(struct object_directory *odb,
142 enum commit_graph_write_flags flags,
143 const struct commit_graph_opts *opts);
144 int write_commit_graph(struct object_directory *odb,
145 - struct string_list *pack_indexes,
145 + const struct string_list *pack_indexes,
146 struct oidset *commits,
147 enum commit_graph_write_flags flags,
148 const struct commit_graph_opts *opts);