http-push: free transfer_request strbuf

When we issue a PUT, we initialize and fill a strbuf embedded in the transfer_request struct. But we never release this buffer, causing a leak. We can fix this by adding a strbuf_release() call to release_request(). If we stopped there, then non-PUT requests would try to release a zero-initialized strbuf. This works OK in practice, but we should try to follow the strbuf API more closely. So instead, we'll always initialize the strbuf when we create the transfer_request struct. That in turn means switching the strbuf_init() call in start_put() to a simple strbuf_grow(). This leak is triggered in t5540. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 24, 2024 at 18:08 UTC 94c62857808bdd6b5b061284eb9dfd13204bd11a
1 file changed +4 -1
http-push.c
+4 -1
@@ -375,7 +375,7 @@ static void start_put(struct transfer_request *request)
375 /* Set it up */
376 git_deflate_init(&stream, zlib_compression_level);
377 size = git_deflate_bound(&stream, len + hdrlen);
378 - strbuf_init(&request->buffer.buf, size);
378 + strbuf_grow(&request->buffer.buf, size);
379 request->buffer.posn = 0;
380
381 /* Compress it */
@@ -515,6 +515,7 @@ static void release_request(struct transfer_request *request)
515
516 free(request->url);
517 free(request->dest);
518 + strbuf_release(&request->buffer.buf);
519 free(request);
520 }
521
@@ -655,6 +656,7 @@ static void add_fetch_request(struct object *obj)
656 CALLOC_ARRAY(request, 1);
657 request->obj = obj;
658 request->state = NEED_FETCH;
659 + strbuf_init(&request->buffer.buf, 0);
660 request->next = request_queue_head;
661 request_queue_head = request;
662
@@ -689,6 +691,7 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
691 request->obj = obj;
692 request->lock = lock;
693 request->state = NEED_PUSH;
694 + strbuf_init(&request->buffer.buf, 0);
695 request->next = request_queue_head;
696 request_queue_head = request;
697