diff mbox series

[21/23] entry: fix leaking pathnames during delayed checkout

Message ID e426fd7ec5b3a93b4110d05fb4e3580c4f6e7d52.1721995576.git.ps@pks.im (mailing list archive)
State Superseded
Headers show
Series Memory leak fixes (pt.3) | expand

Commit Message

Patrick Steinhardt July 26, 2024, 12:18 p.m. UTC
When filtering files during delayed checkout, we pass a string list to
`async_query_available_blobs()`. This list is initialized with NODUP,
and thus inserted strings will not be owned by the list. In the latter
function we then try to hand over ownership by passing an `xstrup()`'d
value to `string_list_insert()`. But this is not how this works: a NODUP
list does not take ownership of allocated strings and will never free
them for the caller.

Fix this issue by initializing the list as `DUP` instead and dropping
the explicit call to `xstrdup()`. This is okay to do given that this is
the single callsite of `async_query_available_blobs()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 convert.c                               | 2 +-
 entry.c                                 | 4 +++-
 t/t2080-parallel-checkout-basics.sh     | 1 +
 t/t2082-parallel-checkout-attributes.sh | 1 +
 4 files changed, 6 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/convert.c b/convert.c
index d8737fe0f2..61a540e212 100644
--- a/convert.c
+++ b/convert.c
@@ -960,7 +960,7 @@  int async_query_available_blobs(const char *cmd, struct string_list *available_p
 	while ((line = packet_read_line(process->out, NULL))) {
 		const char *path;
 		if (skip_prefix(line, "pathname=", &path))
-			string_list_insert(available_paths, xstrdup(path));
+			string_list_insert(available_paths, path);
 		else
 			; /* ignore unknown keys */
 	}
diff --git a/entry.c b/entry.c
index e7ed440ce2..3143b9996b 100644
--- a/entry.c
+++ b/entry.c
@@ -191,7 +191,7 @@  int finish_delayed_checkout(struct checkout *state, int show_progress)
 		progress = start_delayed_progress(_("Filtering content"), dco->paths.nr);
 	while (dco->filters.nr > 0) {
 		for_each_string_list_item(filter, &dco->filters) {
-			struct string_list available_paths = STRING_LIST_INIT_NODUP;
+			struct string_list available_paths = STRING_LIST_INIT_DUP;
 
 			if (!async_query_available_blobs(filter->string, &available_paths)) {
 				/* Filter reported an error */
@@ -245,6 +245,8 @@  int finish_delayed_checkout(struct checkout *state, int show_progress)
 				} else
 					errs = 1;
 			}
+
+			string_list_clear(&available_paths, 0);
 		}
 
 		filter_string_list(&dco->filters, 0, string_is_not_null, NULL);
diff --git a/t/t2080-parallel-checkout-basics.sh b/t/t2080-parallel-checkout-basics.sh
index 5ffe1a41e2..59e5570cb2 100755
--- a/t/t2080-parallel-checkout-basics.sh
+++ b/t/t2080-parallel-checkout-basics.sh
@@ -8,6 +8,7 @@  working tree.
 '
 
 TEST_NO_CREATE_REPO=1
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY/lib-parallel-checkout.sh"
 
diff --git a/t/t2082-parallel-checkout-attributes.sh b/t/t2082-parallel-checkout-attributes.sh
index f3511cd43a..aec55496eb 100755
--- a/t/t2082-parallel-checkout-attributes.sh
+++ b/t/t2082-parallel-checkout-attributes.sh
@@ -10,6 +10,7 @@  properly (without access to the index or attribute stack).
 '
 
 TEST_NO_CREATE_REPO=1
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY/lib-parallel-checkout.sh"
 . "$TEST_DIRECTORY/lib-encoding.sh"