Skip to content

Commit d4a5896

Browse files
remote-curl: fix memory leak in show_http_message()
Fix a memory leak in show_http_message() that was triggered when displaying HTTP error messages before die(). The function would call strbuf_reencode() which modifies the caller's strbuf in place, allocating new memory for the re-encoded string. Since this function is only called immediately before die(), the allocated memory was never explicitly freed, causing leak detectors to report it. The leak became visible when HTTP 429 rate limit retry support was added, which introduced the HTTP_RATE_LIMITED error case. However, the issue existed in pre-existing error paths as well (HTTP_MISSING_TARGET, HTTP_NOAUTH, HTTP_NOMATCHPUBLICKEY) - the new retry logic just made it more visible in tests because retries exercise the error paths more frequently. The leak was detected by LeakSanitizer in t5584 tests that enable retries (maxRetries > 0). Tests with retries disabled passed because they took a different code path or timing. Fix this by making show_http_message() work on a local copy of the message buffer instead of modifying the caller's buffer in place: 1. Create a local strbuf and copy the message into it 2. Perform re-encoding on the local copy if needed 3. Display the message from the local copy 4. Properly release the local copy before returning This ensures all memory allocated by strbuf_reencode() is freed before the function returns, even though die() is called immediately after, eliminating the leak. Signed-off-by: Vaidas Pilkauskas <[email protected]>
1 parent 96613ed commit d4a5896

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

remote-curl.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -371,26 +371,32 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset,
371371
struct strbuf *msg)
372372
{
373373
const char *p, *eol;
374+
struct strbuf msgbuf = STRBUF_INIT;
374375

375376
/*
376377
* We only show text/plain parts, as other types are likely
377378
* to be ugly to look at on the user's terminal.
378379
*/
379380
if (strcmp(type->buf, "text/plain"))
380381
return -1;
382+
383+
strbuf_addbuf(&msgbuf, msg);
381384
if (charset->len)
382-
strbuf_reencode(msg, charset->buf, get_log_output_encoding());
385+
strbuf_reencode(&msgbuf, charset->buf, get_log_output_encoding());
383386

384-
strbuf_trim(msg);
385-
if (!msg->len)
387+
strbuf_trim(&msgbuf);
388+
if (!msgbuf.len) {
389+
strbuf_release(&msgbuf);
386390
return -1;
391+
}
387392

388-
p = msg->buf;
393+
p = msgbuf.buf;
389394
do {
390395
eol = strchrnul(p, '\n');
391396
fprintf(stderr, "remote: %.*s\n", (int)(eol - p), p);
392397
p = eol + 1;
393398
} while(*eol);
399+
strbuf_release(&msgbuf);
394400
return 0;
395401
}
396402

0 commit comments

Comments
 (0)