Skip to content

Commit 8bdb84e

Browse files
peffgitster
authored andcommitted
http: call git_inflate_end() when releasing http_object_request
In new_http_object_request(), we initialize the zlib stream with git_inflate_init(). We must have a matching git_inflate_end() to avoid leaking any memory allocated by zlib. In most cases this happens in finish_http_object_request(), but we don't always get there. If we abort a request mid-stream, then we may clean it up without hitting that function. We can't just add a git_inflate_end() call to the release function, though. That would double-free the cases that did actually finish. Instead, we'll move the call from the finish function to the release function. This does delay it for the cases that do finish, but I don't think it matters. We should have already reached Z_STREAM_END (and complain if we didn't), and we do not record any status code from git_inflate_end(). This leak is triggered by t5550 at least (and probably other dumb-http tests). I did find one other related spot of interest. If we try to read a previously downloaded file and fail, we reset the stream by calling memset() followed by a fresh git_inflate_init(). I don't think this case is triggered in the test suite, but it seemed like an obvious leak, so I added the appropriate git_inflate_end() before the memset() there. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a1bc3c8 commit 8bdb84e

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

http.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2726,6 +2726,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
27262726
* file; also rewind to the beginning of the local file.
27272727
*/
27282728
if (prev_read == -1) {
2729+
git_inflate_end(&freq->stream);
27292730
memset(&freq->stream, 0, sizeof(freq->stream));
27302731
git_inflate_init(&freq->stream);
27312732
the_hash_algo->init_fn(&freq->c);
@@ -2799,7 +2800,6 @@ int finish_http_object_request(struct http_object_request *freq)
27992800
return -1;
28002801
}
28012802

2802-
git_inflate_end(&freq->stream);
28032803
the_hash_algo->final_oid_fn(&freq->real_oid, &freq->c);
28042804
if (freq->zret != Z_STREAM_END) {
28052805
unlink_or_warn(freq->tmpfile.buf);
@@ -2840,6 +2840,7 @@ void release_http_object_request(struct http_object_request **freq_p)
28402840
}
28412841
curl_slist_free_all(freq->headers);
28422842
strbuf_release(&freq->tmpfile);
2843+
git_inflate_end(&freq->stream);
28432844

28442845
free(freq);
28452846
*freq_p = NULL;

0 commit comments

Comments
 (0)