]> git.ipfire.org Git - thirdparty/git.git/commitdiff
entry: fix leaking pathnames during delayed checkout
authorPatrick Steinhardt <ps@pks.im>
Thu, 1 Aug 2024 10:41:06 +0000 (12:41 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 1 Aug 2024 15:47:37 +0000 (08:47 -0700)
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
convert.c
entry.c
t/t2080-parallel-checkout-basics.sh
t/t2082-parallel-checkout-attributes.sh

index d8737fe0f2d60ff372140194bc88e6a1999450e4..61a540e212decde5a4451a2069cf69e0aee0a3d6 100644 (file)
--- 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 e7ed440ce2277ec59fbc89add236329f74ed1aa7..3143b9996bf491f7ceddf2d39de741ed5c35ef11 100644 (file)
--- 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);
index 5ffe1a41e2cd726e00b242a9f289c28c183ef5f0..59e5570cb2d52298ba1c1045d2baef025fd86baf 100755 (executable)
@@ -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"
 
index f3511cd43a9ddc929c886ef7c44f4e4704b6c367..aec55496eb1588f022ada0e967251d4b6833c574 100755 (executable)
@@ -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"