From 63c9bd372e388f5fed77be56771d5ad972f37f8e Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Jun 2024 11:20:42 +0200 Subject: commit: fix leaking parents when calling `commit_tree_extended()` When creating commits via `commit_tree_extended()`, the caller passes in a string list of parents. This call implicitly transfers ownership of that list to the function, which is quite surprising to begin with. But to make matters worse, `commit_tree_extended()` doesn't even bother to free the list of parents in error cases. The result is a memory leak, and one that the caller cannot fix by themselves because they do not know whether parts of the string list have already been released. Refactor the code such that callers can keep ownership of the list of parents, which is getting indicated by parameter being a constant pointer now. Free the lists at the calling site and add a common exit path to those sites as required. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- notes-utils.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'notes-utils.c') diff --git a/notes-utils.c b/notes-utils.c index 671d1969b1..3198c14e4d 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -9,10 +9,11 @@ void create_notes_commit(struct repository *r, struct notes_tree *t, - struct commit_list *parents, + const struct commit_list *parents, const char *msg, size_t msg_len, struct object_id *result_oid) { + struct commit_list *parents_to_free = NULL; struct object_id tree_oid; assert(t->initialized); @@ -27,7 +28,8 @@ void create_notes_commit(struct repository *r, struct commit *parent = lookup_commit(r, &parent_oid); if (repo_parse_commit(r, parent)) die("Failed to find/parse commit %s", t->ref); - commit_list_insert(parent, &parents); + commit_list_insert(parent, &parents_to_free); + parents = parents_to_free; } /* else: t->ref points to nothing, assume root/orphan commit */ } @@ -35,6 +37,8 @@ void create_notes_commit(struct repository *r, if (commit_tree(msg, msg_len, &tree_oid, parents, result_oid, NULL, NULL)) die("Failed to commit notes tree to database"); + + free_commit_list(parents_to_free); } void commit_notes(struct repository *r, struct notes_tree *t, const char *msg) -- cgit v1.2.3