]> git.ipfire.org Git - thirdparty/git.git/commitdiff
remote: plug memory leaks
authorJunio C Hamano <gitster@pobox.com>
Sat, 25 Jul 2026 16:03:24 +0000 (09:03 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 25 Jul 2026 17:13:37 +0000 (10:13 -0700)
The in-core data structure used to keep track of
'url.<real>.{insteadOf,pushInsteadOf} = <alias>' settings is not
properly cleaned up when the process is done with it.

'struct rewrites' is embedded in 'remote_state' and serves as the
top level of the rewrite data.  This holds an array of a variable
number of pointers to 'struct rewrite' allocated individually on the
heap.  Each 'struct rewrite' holds a '.base' string and an array of
'struct counted_string' called '.instead_of', which is allocated
contiguously on the heap.  Each 'struct counted_string' has a
pointer to a string allocated on the heap.

Amid these pointers, rewrites_release() fails to free everything
other than 'struct rewrite''s '.base' member and the 'struct rewrite'
instances themselves.

Fix rewrites_release() to also free the contiguous array storing
'.instead_of', the string pointers within each '.instead_of' element,
and each 'struct rewrite' instance individually allocated on the heap.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
remote.c

index a664cd166aa3b910c239645093782f7be475282f..6c84adb36a3f0d52dca5d9bd0bf23f1d86ba60df 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -304,8 +304,15 @@ static struct rewrite *make_rewrite(struct rewrites *r,
 
 static void rewrites_release(struct rewrites *r)
 {
-       for (int i = 0; i < r->rewrite_nr; i++)
-               free((char *)r->rewrite[i]->base);
+       for (int i = 0; i < r->rewrite_nr; i++) {
+               struct rewrite *rewrite = r->rewrite[i];
+
+               free((char *)rewrite->base);
+               for (int j = 0; j < rewrite->instead_of_nr; j++)
+                       free((char *)rewrite->instead_of[j].s);
+               free(rewrite->instead_of);
+               free(rewrite);
+       }
        free(r->rewrite);
        memset(r, 0, sizeof(*r));
 }