From: Junio C Hamano Date: Sat, 25 Jul 2026 16:03:24 +0000 (-0700) Subject: remote: plug memory leaks X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dcef3bf041c949061878803d3b7c7f7e2373b413;p=thirdparty%2Fgit.git remote: plug memory leaks The in-core data structure used to keep track of 'url..{insteadOf,pushInsteadOf} = ' 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 --- diff --git a/remote.c b/remote.c index a664cd166a..6c84adb36a 100644 --- 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)); }