]> git.ipfire.org Git - thirdparty/git.git/commitdiff
wt-status: fix leaking buffer with sparse directories
authorPatrick Steinhardt <ps@pks.im>
Mon, 30 Sep 2024 09:13:24 +0000 (11:13 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 30 Sep 2024 18:23:03 +0000 (11:23 -0700)
When hitting a sparse directory in `wt_status_collect_changes_initial()`
we use a `struct strbuf` to assemble the directory's name. We never free
that buffer though, causing a memory leak.

Fix the leak by releasing the buffer. While at it, move the buffer
outside of the loop and reset it to save on some wasteful allocations.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t1092-sparse-checkout-compatibility.sh
wt-status.c

index eb32da2a7f2ad6f14822278523849a8c67aa8476..55efafe4e0c56fa8d3cae2ba7d24bdd4c2bd69a3 100755 (executable)
@@ -5,6 +5,7 @@ test_description='compare full workdir to sparse workdir'
 GIT_TEST_SPLIT_INDEX=0
 GIT_TEST_SPARSE_INDEX=
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index 6a6397ca8f12ba7d6b11eb8e38a28f19d2767b8b..6a8c05d1cff165dda8f42b843bf78490ac624d4e 100644 (file)
@@ -717,6 +717,7 @@ static int add_file_to_list(const struct object_id *oid,
 static void wt_status_collect_changes_initial(struct wt_status *s)
 {
        struct index_state *istate = s->repo->index;
+       struct strbuf base = STRBUF_INIT;
        int i;
 
        for (i = 0; i < istate->cache_nr; i++) {
@@ -735,7 +736,6 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
                         * expanding the trees to find the elements that are new in this
                         * tree and marking them with DIFF_STATUS_ADDED.
                         */
-                       struct strbuf base = STRBUF_INIT;
                        struct pathspec ps = { 0 };
                        struct tree *tree = lookup_tree(istate->repo, &ce->oid);
 
@@ -743,9 +743,11 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
                        ps.has_wildcard = 1;
                        ps.max_depth = -1;
 
+                       strbuf_reset(&base);
                        strbuf_add(&base, ce->name, ce->ce_namelen);
                        read_tree_at(istate->repo, tree, &base, 0, &ps,
                                     add_file_to_list, s);
+
                        continue;
                }
 
@@ -772,6 +774,8 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
                        s->committable = 1;
                }
        }
+
+       strbuf_release(&base);
 }
 
 static void wt_status_collect_untracked(struct wt_status *s)