Skip to content

Commit 59ee4f7

Browse files
committed
Merge branch 'jk/http-leakfixes'
Leakfixes. * jk/http-leakfixes: (28 commits) http-push: clean up local_refs at exit http-push: clean up loose request when falling back to packed http-push: clean up objects list http-push: free xml_ctx.cdata after use http-push: free remote_ls_ctx.dentry_name http-push: free transfer_request strbuf http-push: free transfer_request dest field http-push: free curl header lists http-push: free repo->url string http-push: clear refspecs before exiting http-walker: free fake packed_git list remote-curl: free HEAD ref with free_one_ref() http: stop leaking buffer in http_get_info_packs() http: call git_inflate_end() when releasing http_object_request http: fix leak of http_object_request struct http: fix leak when redacting cookies from curl trace transport-helper: fix leak of dummy refs_list fetch-pack: clear pack lockfiles list fetch: free "raw" string when shrinking refspec transport-helper: fix strbuf leak in push_refs_with_push() ...
2 parents 365529e + f4c768c commit 59ee4f7

29 files changed

+123
-39
lines changed

builtin/fetch-pack.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ int cmd_fetch_pack(int argc,
5353
struct ref *fetched_refs = NULL, *remote_refs = NULL;
5454
const char *dest = NULL;
5555
struct ref **sought = NULL;
56+
struct ref **sought_to_free = NULL;
5657
int nr_sought = 0, alloc_sought = 0;
5758
int fd[2];
5859
struct string_list pack_lockfiles = STRING_LIST_INIT_DUP;
@@ -243,6 +244,13 @@ int cmd_fetch_pack(int argc,
243244
BUG("unknown protocol version");
244245
}
245246

247+
/*
248+
* Create a shallow copy of `sought` so that we can free all of its entries.
249+
* This is because `fetch_pack()` will modify the array to evict some
250+
* entries, but won't free those.
251+
*/
252+
DUP_ARRAY(sought_to_free, sought, nr_sought);
253+
246254
fetched_refs = fetch_pack(&args, fd, remote_refs, sought, nr_sought,
247255
&shallow, pack_lockfiles_ptr, version);
248256

@@ -280,9 +288,13 @@ int cmd_fetch_pack(int argc,
280288
oid_to_hex(&ref->old_oid), ref->name);
281289

282290
for (size_t i = 0; i < nr_sought; i++)
283-
free_one_ref(sought[i]);
291+
free_one_ref(sought_to_free[i]);
292+
free(sought_to_free);
284293
free(sought);
285294
free_refs(fetched_refs);
286295
free_refs(remote_refs);
296+
list_objects_filter_release(&args.filter_options);
297+
oid_array_clear(&shallow);
298+
string_list_clear(&pack_lockfiles, 0);
287299
return ret;
288300
}

builtin/fetch.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ static void filter_prefetch_refspec(struct refspec *rs)
456456

457457
free(rs->items[i].src);
458458
free(rs->items[i].dst);
459+
free(rs->raw[i]);
459460

460461
for (j = i + 1; j < rs->nr; j++) {
461462
rs->items[j - 1] = rs->items[j];

builtin/push.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ int cmd_push(int argc,
669669
rc = do_push(flags, push_options, remote);
670670
string_list_clear(&push_options_cmdline, 0);
671671
string_list_clear(&push_options_config, 0);
672+
clear_cas_option(&cas);
672673
if (rc == -1)
673674
usage_with_options(push_usage, options);
674675
else

builtin/send-pack.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,5 +343,7 @@ int cmd_send_pack(int argc,
343343
free_refs(remote_refs);
344344
free_refs(local_refs);
345345
refspec_clear(&rs);
346+
oid_array_clear(&shallow);
347+
clear_cas_option(&cas);
346348
return ret;
347349
}

commit.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,8 @@ int repo_parse_commit_internal(struct repository *r,
595595
}
596596

597597
ret = parse_commit_buffer(r, item, buffer, size, 0);
598-
if (save_commit_buffer && !ret) {
598+
if (save_commit_buffer && !ret &&
599+
!get_cached_commit_buffer(r, item, NULL)) {
599600
set_commit_buffer(r, item, buffer, size);
600601
return 0;
601602
}

connect.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,7 @@ struct child_process *git_connect(int fd[2], const char *url,
14851485

14861486
free(hostandport);
14871487
free(path);
1488+
child_process_clear(conn);
14881489
free(conn);
14891490
strbuf_release(&cmd);
14901491
return NULL;

http-fetch.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ int cmd_main(int argc, const char **argv)
106106
int nongit;
107107
struct object_id packfile_hash;
108108
struct strvec index_pack_args = STRVEC_INIT;
109+
int ret;
109110

110111
setup_git_directory_gently(&nongit);
111112

@@ -157,8 +158,8 @@ int cmd_main(int argc, const char **argv)
157158

158159
fetch_single_packfile(&packfile_hash, argv[arg],
159160
index_pack_args.v);
160-
161-
return 0;
161+
ret = 0;
162+
goto out;
162163
}
163164

164165
if (index_pack_args.nr)
@@ -170,7 +171,12 @@ int cmd_main(int argc, const char **argv)
170171
commit_id = (char **) &argv[arg++];
171172
commits = 1;
172173
}
173-
return fetch_using_walker(argv[arg], get_verbosely, get_recover,
174-
commits, commit_id, write_ref,
175-
commits_on_stdin);
174+
175+
ret = fetch_using_walker(argv[arg], get_verbosely, get_recover,
176+
commits, commit_id, write_ref,
177+
commits_on_stdin);
178+
179+
out:
180+
strvec_clear(&index_pack_args);
181+
return ret;
176182
}

http-push.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ static void start_fetch_loose(struct transfer_request *request)
275275
if (!start_active_slot(slot)) {
276276
fprintf(stderr, "Unable to start GET request\n");
277277
repo->can_update_info_refs = 0;
278-
release_http_object_request(obj_req);
278+
release_http_object_request(&obj_req);
279279
release_request(request);
280280
}
281281
}
@@ -375,7 +375,7 @@ static void start_put(struct transfer_request *request)
375375
/* Set it up */
376376
git_deflate_init(&stream, zlib_compression_level);
377377
size = git_deflate_bound(&stream, len + hdrlen);
378-
strbuf_init(&request->buffer.buf, size);
378+
strbuf_grow(&request->buffer.buf, size);
379379
request->buffer.posn = 0;
380380

381381
/* Compress it */
@@ -437,9 +437,11 @@ static void start_move(struct transfer_request *request)
437437
if (start_active_slot(slot)) {
438438
request->slot = slot;
439439
request->state = RUN_MOVE;
440+
request->headers = dav_headers;
440441
} else {
441442
request->state = ABORTED;
442443
FREE_AND_NULL(request->url);
444+
curl_slist_free_all(dav_headers);
443445
}
444446
}
445447

@@ -512,6 +514,8 @@ static void release_request(struct transfer_request *request)
512514
}
513515

514516
free(request->url);
517+
free(request->dest);
518+
strbuf_release(&request->buffer.buf);
515519
free(request);
516520
}
517521

@@ -578,9 +582,10 @@ static void finish_request(struct transfer_request *request)
578582
if (obj_req->rename == 0)
579583
request->obj->flags |= (LOCAL | REMOTE);
580584

585+
release_http_object_request(&obj_req);
586+
581587
/* Try fetching packed if necessary */
582588
if (request->obj->flags & LOCAL) {
583-
release_http_object_request(obj_req);
584589
release_request(request);
585590
} else
586591
start_fetch_packed(request);
@@ -649,12 +654,10 @@ static void add_fetch_request(struct object *obj)
649654
return;
650655

651656
obj->flags |= FETCHING;
652-
request = xmalloc(sizeof(*request));
657+
CALLOC_ARRAY(request, 1);
653658
request->obj = obj;
654-
request->url = NULL;
655-
request->lock = NULL;
656-
request->headers = NULL;
657659
request->state = NEED_FETCH;
660+
strbuf_init(&request->buffer.buf, 0);
658661
request->next = request_queue_head;
659662
request_queue_head = request;
660663

@@ -685,12 +688,11 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
685688
}
686689

687690
obj->flags |= PUSHING;
688-
request = xmalloc(sizeof(*request));
691+
CALLOC_ARRAY(request, 1);
689692
request->obj = obj;
690-
request->url = NULL;
691693
request->lock = lock;
692-
request->headers = NULL;
693694
request->state = NEED_PUSH;
695+
strbuf_init(&request->buffer.buf, 0);
694696
request->next = request_queue_head;
695697
request_queue_head = request;
696698

@@ -912,6 +914,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
912914
result = XML_Parse(parser, in_buffer.buf,
913915
in_buffer.len, 1);
914916
free(ctx.name);
917+
free(ctx.cdata);
915918
if (result != XML_STATUS_OK) {
916919
fprintf(stderr, "XML error: %s\n",
917920
XML_ErrorString(
@@ -1169,6 +1172,7 @@ static void remote_ls(const char *path, int flags,
11691172
result = XML_Parse(parser, in_buffer.buf,
11701173
in_buffer.len, 1);
11711174
free(ctx.name);
1175+
free(ctx.cdata);
11721176

11731177
if (result != XML_STATUS_OK) {
11741178
fprintf(stderr, "XML error: %s\n",
@@ -1182,6 +1186,7 @@ static void remote_ls(const char *path, int flags,
11821186
}
11831187

11841188
free(ls.path);
1189+
free(ls.dentry_name);
11851190
free(url);
11861191
strbuf_release(&out_buffer.buf);
11871192
strbuf_release(&in_buffer);
@@ -1370,9 +1375,13 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock)
13701375
}
13711376

13721377
while (objects) {
1378+
struct object_list *next = objects->next;
1379+
13731380
if (!(objects->item->flags & UNINTERESTING))
13741381
count += add_send_request(objects->item, lock);
1375-
objects = objects->next;
1382+
1383+
free(objects);
1384+
objects = next;
13761385
}
13771386

13781387
return count;
@@ -1398,6 +1407,7 @@ static int update_remote(const struct object_id *oid, struct remote_lock *lock)
13981407
if (start_active_slot(slot)) {
13991408
run_active_slot(slot);
14001409
strbuf_release(&out_buffer.buf);
1410+
curl_slist_free_all(dav_headers);
14011411
if (results.curl_result != CURLE_OK) {
14021412
fprintf(stderr,
14031413
"PUT error: curl result=%d, HTTP code=%ld\n",
@@ -1407,6 +1417,7 @@ static int update_remote(const struct object_id *oid, struct remote_lock *lock)
14071417
}
14081418
} else {
14091419
strbuf_release(&out_buffer.buf);
1420+
curl_slist_free_all(dav_headers);
14101421
fprintf(stderr, "Unable to start PUT request\n");
14111422
return 0;
14121423
}
@@ -1516,6 +1527,7 @@ static void update_remote_info_refs(struct remote_lock *lock)
15161527
results.curl_result, results.http_code);
15171528
}
15181529
}
1530+
curl_slist_free_all(dav_headers);
15191531
}
15201532
strbuf_release(&buffer.buf);
15211533
}
@@ -1707,7 +1719,7 @@ int cmd_main(int argc, const char **argv)
17071719
int rc = 0;
17081720
int i;
17091721
int new_refs;
1710-
struct ref *ref, *local_refs;
1722+
struct ref *ref, *local_refs = NULL;
17111723

17121724
CALLOC_ARRAY(repo, 1);
17131725

@@ -1972,6 +1984,7 @@ int cmd_main(int argc, const char **argv)
19721984
cleanup:
19731985
if (info_ref_lock)
19741986
unlock_remote(info_ref_lock);
1987+
free(repo->url);
19751988
free(repo);
19761989

19771990
http_cleanup();
@@ -1983,5 +1996,8 @@ int cmd_main(int argc, const char **argv)
19831996
request = next_request;
19841997
}
19851998

1999+
refspec_clear(&rs);
2000+
free_refs(local_refs);
2001+
19862002
return rc;
19872003
}

http-walker.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static void start_object_request(struct object_request *obj_req)
7474
obj_req->state = ACTIVE;
7575
if (!start_active_slot(slot)) {
7676
obj_req->state = ABORTED;
77-
release_http_object_request(req);
77+
release_http_object_request(&req);
7878
return;
7979
}
8080
}
@@ -110,7 +110,7 @@ static void process_object_response(void *callback_data)
110110
if (obj_req->repo->next) {
111111
obj_req->repo =
112112
obj_req->repo->next;
113-
release_http_object_request(obj_req->req);
113+
release_http_object_request(&obj_req->req);
114114
start_object_request(obj_req);
115115
return;
116116
}
@@ -495,7 +495,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
495495

496496
if (repo_has_object_file(the_repository, &obj_req->oid)) {
497497
if (obj_req->req)
498-
abort_http_object_request(obj_req->req);
498+
abort_http_object_request(&obj_req->req);
499499
abort_object_request(obj_req);
500500
return 0;
501501
}
@@ -543,7 +543,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
543543
strbuf_release(&buf);
544544
}
545545

546-
release_http_object_request(req);
546+
release_http_object_request(&obj_req->req);
547547
release_object_request(obj_req);
548548
return ret;
549549
}
@@ -579,8 +579,18 @@ static void cleanup(struct walker *walker)
579579
if (data) {
580580
alt = data->alt;
581581
while (alt) {
582+
struct packed_git *pack;
583+
582584
alt_next = alt->next;
583585

586+
pack = alt->packs;
587+
while (pack) {
588+
struct packed_git *pack_next = pack->next;
589+
close_pack(pack);
590+
free(pack);
591+
pack = pack_next;
592+
}
593+
584594
free(alt->base);
585595
free(alt);
586596

0 commit comments

Comments
 (0)