Skip to content

Commit 59ee4f7

Browse files
committedOct 2, 2024
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

+13-1
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

+1
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

+1
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

+2
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

+2-1
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

+1
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

+11-5
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

+28-12
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

+14-4
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

‎http.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,7 @@ static int redact_sensitive_header(struct strbuf *header, size_t offset)
800800

801801
strbuf_setlen(header, sensitive_header - header->buf);
802802
strbuf_addbuf(header, &redacted_header);
803+
strbuf_release(&redacted_header);
803804
ret = 1;
804805
}
805806
return ret;
@@ -2474,6 +2475,7 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
24742475

24752476
cleanup:
24762477
free(url);
2478+
strbuf_release(&buf);
24772479
return ret;
24782480
}
24792481

@@ -2725,6 +2727,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
27252727
* file; also rewind to the beginning of the local file.
27262728
*/
27272729
if (prev_read == -1) {
2730+
git_inflate_end(&freq->stream);
27282731
memset(&freq->stream, 0, sizeof(freq->stream));
27292732
git_inflate_init(&freq->stream);
27302733
the_hash_algo->init_fn(&freq->c);
@@ -2798,7 +2801,6 @@ int finish_http_object_request(struct http_object_request *freq)
27982801
return -1;
27992802
}
28002803

2801-
git_inflate_end(&freq->stream);
28022804
the_hash_algo->final_oid_fn(&freq->real_oid, &freq->c);
28032805
if (freq->zret != Z_STREAM_END) {
28042806
unlink_or_warn(freq->tmpfile.buf);
@@ -2815,15 +2817,17 @@ int finish_http_object_request(struct http_object_request *freq)
28152817
return freq->rename;
28162818
}
28172819

2818-
void abort_http_object_request(struct http_object_request *freq)
2820+
void abort_http_object_request(struct http_object_request **freq_p)
28192821
{
2822+
struct http_object_request *freq = *freq_p;
28202823
unlink_or_warn(freq->tmpfile.buf);
28212824

2822-
release_http_object_request(freq);
2825+
release_http_object_request(freq_p);
28232826
}
28242827

2825-
void release_http_object_request(struct http_object_request *freq)
2828+
void release_http_object_request(struct http_object_request **freq_p)
28262829
{
2830+
struct http_object_request *freq = *freq_p;
28272831
if (freq->localfile != -1) {
28282832
close(freq->localfile);
28292833
freq->localfile = -1;
@@ -2837,4 +2841,8 @@ void release_http_object_request(struct http_object_request *freq)
28372841
}
28382842
curl_slist_free_all(freq->headers);
28392843
strbuf_release(&freq->tmpfile);
2844+
git_inflate_end(&freq->stream);
2845+
2846+
free(freq);
2847+
*freq_p = NULL;
28402848
}

‎http.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ struct http_object_request *new_http_object_request(
240240
const char *base_url, const struct object_id *oid);
241241
void process_http_object_request(struct http_object_request *freq);
242242
int finish_http_object_request(struct http_object_request *freq);
243-
void abort_http_object_request(struct http_object_request *freq);
244-
void release_http_object_request(struct http_object_request *freq);
243+
void abort_http_object_request(struct http_object_request **freq);
244+
void release_http_object_request(struct http_object_request **freq);
245245

246246
/*
247247
* Instead of using environment variables to determine if curl tracing happens,

‎refspec.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ void refspec_clear(struct refspec *rs)
225225
rs->nr = 0;
226226

227227
for (i = 0; i < rs->raw_nr; i++)
228-
free((char *)rs->raw[i]);
228+
free(rs->raw[i]);
229229
FREE_AND_NULL(rs->raw);
230230
rs->raw_alloc = 0;
231231
rs->raw_nr = 0;

‎refspec.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct refspec {
4343
int alloc;
4444
int nr;
4545

46-
const char **raw;
46+
char **raw;
4747
int raw_alloc;
4848
int raw_nr;
4949

‎remote-curl.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ static struct ref *parse_info_refs(struct discovery *heads)
347347
ref->next = refs;
348348
refs = ref;
349349
} else {
350-
free(ref);
350+
free_one_ref(ref);
351351
}
352352

353353
return refs;

‎remote.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2544,7 +2544,7 @@ struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map)
25442544
/*
25452545
* Compare-and-swap
25462546
*/
2547-
static void clear_cas_option(struct push_cas_option *cas)
2547+
void clear_cas_option(struct push_cas_option *cas)
25482548
{
25492549
int i;
25502550

‎remote.h

+1
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ struct push_cas_option {
409409
};
410410

411411
int parseopt_push_cas_option(const struct option *, const char *arg, int unset);
412+
void clear_cas_option(struct push_cas_option *);
412413

413414
int is_empty_cas(const struct push_cas_option *);
414415
void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);

‎shallow.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,11 @@ int unregister_shallow(const struct object_id *oid)
5151
int pos = commit_graft_pos(the_repository, oid);
5252
if (pos < 0)
5353
return -1;
54-
if (pos + 1 < the_repository->parsed_objects->grafts_nr) {
55-
free(the_repository->parsed_objects->grafts[pos]);
54+
free(the_repository->parsed_objects->grafts[pos]);
55+
if (pos + 1 < the_repository->parsed_objects->grafts_nr)
5656
MOVE_ARRAY(the_repository->parsed_objects->grafts + pos,
5757
the_repository->parsed_objects->grafts + pos + 1,
5858
the_repository->parsed_objects->grafts_nr - pos - 1);
59-
}
6059
the_repository->parsed_objects->grafts_nr--;
6160
return 0;
6261
}

‎t/t5500-fetch-pack.sh

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ test_description='Testing multi_ack pack fetching'
88
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
99
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1010

11+
TEST_PASSES_SANITIZE_LEAK=true
1112
. ./test-lib.sh
1213

1314
# Test fetch-pack/upload-pack pair.

‎t/t5539-fetch-http-shallow.sh

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_description='fetch/clone from a shallow clone over http'
55
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
66
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910
. "$TEST_DIRECTORY"/lib-httpd.sh
1011
start_httpd

‎t/t5540-http-push-webdav.sh

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This test runs various sanity checks on http-push.'
1010
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
1111
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1212

13+
TEST_PASSES_SANITIZE_LEAK=true
1314
. ./test-lib.sh
1415

1516
if git http-push > /dev/null 2>&1 || [ $? -eq 128 ]

‎t/t5541-http-push-smart.sh

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ test_description='test smart pushing over http via http-backend'
77
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
88
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
99

10+
TEST_PASSES_SANITIZE_LEAK=true
1011
. ./test-lib.sh
1112

1213
ROOT_PATH="$PWD"

‎t/t5542-push-http-shallow.sh

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_description='push from/to a shallow clone over http'
55
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
66
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910
. "$TEST_DIRECTORY"/lib-httpd.sh
1011
start_httpd

‎t/t5550-http-fetch-dumb.sh

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ test_description='test dumb fetching over http via static file'
44
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
55
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
66

7+
TEST_PASSES_SANITIZE_LEAK=true
78
. ./test-lib.sh
89

910
if test_have_prereq !REFFILES

‎t/t5551-http-fetch-smart.sh

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_description="test smart fetching over http via http-backend ($HTTP_PROTO)"
55
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
66
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910
. "$TEST_DIRECTORY"/lib-httpd.sh
1011
test "$HTTP_PROTO" = "HTTP/2" && enable_http2

‎t/t5582-fetch-negative-refspec.sh

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ test_description='"git fetch" with negative refspecs.
88
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
99
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1010

11+
TEST_PASSES_SANITIZE_LEAK=true
1112
. ./test-lib.sh
1213

1314
test_expect_success setup '

‎t/t5619-clone-local-ambiguous-transport.sh

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
test_description='test local clone with ambiguous transport'
44

5+
TEST_PASSES_SANITIZE_LEAK=true
56
. ./test-lib.sh
67
. "$TEST_DIRECTORY/lib-httpd.sh"
78

‎t/t5700-protocol-v1.sh

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export GIT_TEST_PROTOCOL_VERSION
1111
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
1212
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1313

14+
TEST_PASSES_SANITIZE_LEAK=true
1415
. ./test-lib.sh
1516

1617
# Test protocol v1 with 'git://' transport

‎transport-helper.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,14 @@ static int fetch_refs(struct transport *transport,
717717
return -1;
718718
}
719719

720-
if (!data->get_refs_list_called)
721-
get_refs_list_using_list(transport, 0);
720+
if (!data->get_refs_list_called) {
721+
/*
722+
* We do not care about the list of refs returned, but only
723+
* that the "list" command was sent.
724+
*/
725+
struct ref *dummy = get_refs_list_using_list(transport, 0);
726+
free_refs(dummy);
727+
}
722728

723729
count = 0;
724730
for (i = 0; i < nr_heads; i++)
@@ -1023,6 +1029,7 @@ static int push_refs_with_push(struct transport *transport,
10231029
if (atomic) {
10241030
reject_atomic_push(remote_refs, mirror);
10251031
string_list_clear(&cas_options, 0);
1032+
strbuf_release(&buf);
10261033
return 0;
10271034
} else
10281035
continue;

‎transport.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ static int fetch_refs_via_pack(struct transport *transport,
414414
struct git_transport_data *data = transport->data;
415415
struct ref *refs = NULL;
416416
struct fetch_pack_args args;
417-
struct ref *refs_tmp = NULL;
417+
struct ref *refs_tmp = NULL, **to_fetch_dup = NULL;
418418

419419
memset(&args, 0, sizeof(args));
420420
args.uploadpack = data->options.uploadpack;
@@ -477,6 +477,14 @@ static int fetch_refs_via_pack(struct transport *transport,
477477
goto cleanup;
478478
}
479479

480+
/*
481+
* Create a shallow copy of `sought` so that we can free all of its entries.
482+
* This is because `fetch_pack()` will modify the array to evict some
483+
* entries, but won't free those.
484+
*/
485+
DUP_ARRAY(to_fetch_dup, to_fetch, nr_heads);
486+
to_fetch = to_fetch_dup;
487+
480488
refs = fetch_pack(&args, data->fd,
481489
refs_tmp ? refs_tmp : transport->remote_refs,
482490
to_fetch, nr_heads, &data->shallow,
@@ -500,6 +508,7 @@ static int fetch_refs_via_pack(struct transport *transport,
500508
ret = -1;
501509
data->conn = NULL;
502510

511+
free(to_fetch_dup);
503512
free_refs(refs_tmp);
504513
free_refs(refs);
505514
list_objects_filter_release(&args.filter_options);

0 commit comments

Comments
 (0)
Please sign in to comment.