1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 04:49:43 +01:00

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()
  ...
This commit is contained in:
Junio C Hamano 2024-10-02 07:46:26 -07:00
commit 59ee4f7013
29 changed files with 123 additions and 39 deletions

View file

@ -53,6 +53,7 @@ int cmd_fetch_pack(int argc,
struct ref *fetched_refs = NULL, *remote_refs = NULL; struct ref *fetched_refs = NULL, *remote_refs = NULL;
const char *dest = NULL; const char *dest = NULL;
struct ref **sought = NULL; struct ref **sought = NULL;
struct ref **sought_to_free = NULL;
int nr_sought = 0, alloc_sought = 0; int nr_sought = 0, alloc_sought = 0;
int fd[2]; int fd[2];
struct string_list pack_lockfiles = STRING_LIST_INIT_DUP; struct string_list pack_lockfiles = STRING_LIST_INIT_DUP;
@ -243,6 +244,13 @@ int cmd_fetch_pack(int argc,
BUG("unknown protocol version"); BUG("unknown protocol version");
} }
/*
* Create a shallow copy of `sought` so that we can free all of its entries.
* This is because `fetch_pack()` will modify the array to evict some
* entries, but won't free those.
*/
DUP_ARRAY(sought_to_free, sought, nr_sought);
fetched_refs = fetch_pack(&args, fd, remote_refs, sought, nr_sought, fetched_refs = fetch_pack(&args, fd, remote_refs, sought, nr_sought,
&shallow, pack_lockfiles_ptr, version); &shallow, pack_lockfiles_ptr, version);
@ -280,9 +288,13 @@ int cmd_fetch_pack(int argc,
oid_to_hex(&ref->old_oid), ref->name); oid_to_hex(&ref->old_oid), ref->name);
for (size_t i = 0; i < nr_sought; i++) for (size_t i = 0; i < nr_sought; i++)
free_one_ref(sought[i]); free_one_ref(sought_to_free[i]);
free(sought_to_free);
free(sought); free(sought);
free_refs(fetched_refs); free_refs(fetched_refs);
free_refs(remote_refs); free_refs(remote_refs);
list_objects_filter_release(&args.filter_options);
oid_array_clear(&shallow);
string_list_clear(&pack_lockfiles, 0);
return ret; return ret;
} }

View file

@ -456,6 +456,7 @@ static void filter_prefetch_refspec(struct refspec *rs)
free(rs->items[i].src); free(rs->items[i].src);
free(rs->items[i].dst); free(rs->items[i].dst);
free(rs->raw[i]);
for (j = i + 1; j < rs->nr; j++) { for (j = i + 1; j < rs->nr; j++) {
rs->items[j - 1] = rs->items[j]; rs->items[j - 1] = rs->items[j];

View file

@ -669,6 +669,7 @@ int cmd_push(int argc,
rc = do_push(flags, push_options, remote); rc = do_push(flags, push_options, remote);
string_list_clear(&push_options_cmdline, 0); string_list_clear(&push_options_cmdline, 0);
string_list_clear(&push_options_config, 0); string_list_clear(&push_options_config, 0);
clear_cas_option(&cas);
if (rc == -1) if (rc == -1)
usage_with_options(push_usage, options); usage_with_options(push_usage, options);
else else

View file

@ -343,5 +343,7 @@ int cmd_send_pack(int argc,
free_refs(remote_refs); free_refs(remote_refs);
free_refs(local_refs); free_refs(local_refs);
refspec_clear(&rs); refspec_clear(&rs);
oid_array_clear(&shallow);
clear_cas_option(&cas);
return ret; return ret;
} }

View file

@ -595,7 +595,8 @@ int repo_parse_commit_internal(struct repository *r,
} }
ret = parse_commit_buffer(r, item, buffer, size, 0); ret = parse_commit_buffer(r, item, buffer, size, 0);
if (save_commit_buffer && !ret) { if (save_commit_buffer && !ret &&
!get_cached_commit_buffer(r, item, NULL)) {
set_commit_buffer(r, item, buffer, size); set_commit_buffer(r, item, buffer, size);
return 0; return 0;
} }

View file

@ -1485,6 +1485,7 @@ struct child_process *git_connect(int fd[2], const char *url,
free(hostandport); free(hostandport);
free(path); free(path);
child_process_clear(conn);
free(conn); free(conn);
strbuf_release(&cmd); strbuf_release(&cmd);
return NULL; return NULL;

View file

@ -106,6 +106,7 @@ int cmd_main(int argc, const char **argv)
int nongit; int nongit;
struct object_id packfile_hash; struct object_id packfile_hash;
struct strvec index_pack_args = STRVEC_INIT; struct strvec index_pack_args = STRVEC_INIT;
int ret;
setup_git_directory_gently(&nongit); setup_git_directory_gently(&nongit);
@ -157,8 +158,8 @@ int cmd_main(int argc, const char **argv)
fetch_single_packfile(&packfile_hash, argv[arg], fetch_single_packfile(&packfile_hash, argv[arg],
index_pack_args.v); index_pack_args.v);
ret = 0;
return 0; goto out;
} }
if (index_pack_args.nr) if (index_pack_args.nr)
@ -170,7 +171,12 @@ int cmd_main(int argc, const char **argv)
commit_id = (char **) &argv[arg++]; commit_id = (char **) &argv[arg++];
commits = 1; commits = 1;
} }
return fetch_using_walker(argv[arg], get_verbosely, get_recover,
ret = fetch_using_walker(argv[arg], get_verbosely, get_recover,
commits, commit_id, write_ref, commits, commit_id, write_ref,
commits_on_stdin); commits_on_stdin);
out:
strvec_clear(&index_pack_args);
return ret;
} }

View file

@ -275,7 +275,7 @@ static void start_fetch_loose(struct transfer_request *request)
if (!start_active_slot(slot)) { if (!start_active_slot(slot)) {
fprintf(stderr, "Unable to start GET request\n"); fprintf(stderr, "Unable to start GET request\n");
repo->can_update_info_refs = 0; repo->can_update_info_refs = 0;
release_http_object_request(obj_req); release_http_object_request(&obj_req);
release_request(request); release_request(request);
} }
} }
@ -375,7 +375,7 @@ static void start_put(struct transfer_request *request)
/* Set it up */ /* Set it up */
git_deflate_init(&stream, zlib_compression_level); git_deflate_init(&stream, zlib_compression_level);
size = git_deflate_bound(&stream, len + hdrlen); size = git_deflate_bound(&stream, len + hdrlen);
strbuf_init(&request->buffer.buf, size); strbuf_grow(&request->buffer.buf, size);
request->buffer.posn = 0; request->buffer.posn = 0;
/* Compress it */ /* Compress it */
@ -437,9 +437,11 @@ static void start_move(struct transfer_request *request)
if (start_active_slot(slot)) { if (start_active_slot(slot)) {
request->slot = slot; request->slot = slot;
request->state = RUN_MOVE; request->state = RUN_MOVE;
request->headers = dav_headers;
} else { } else {
request->state = ABORTED; request->state = ABORTED;
FREE_AND_NULL(request->url); FREE_AND_NULL(request->url);
curl_slist_free_all(dav_headers);
} }
} }
@ -512,6 +514,8 @@ static void release_request(struct transfer_request *request)
} }
free(request->url); free(request->url);
free(request->dest);
strbuf_release(&request->buffer.buf);
free(request); free(request);
} }
@ -578,9 +582,10 @@ static void finish_request(struct transfer_request *request)
if (obj_req->rename == 0) if (obj_req->rename == 0)
request->obj->flags |= (LOCAL | REMOTE); request->obj->flags |= (LOCAL | REMOTE);
release_http_object_request(&obj_req);
/* Try fetching packed if necessary */ /* Try fetching packed if necessary */
if (request->obj->flags & LOCAL) { if (request->obj->flags & LOCAL) {
release_http_object_request(obj_req);
release_request(request); release_request(request);
} else } else
start_fetch_packed(request); start_fetch_packed(request);
@ -649,12 +654,10 @@ static void add_fetch_request(struct object *obj)
return; return;
obj->flags |= FETCHING; obj->flags |= FETCHING;
request = xmalloc(sizeof(*request)); CALLOC_ARRAY(request, 1);
request->obj = obj; request->obj = obj;
request->url = NULL;
request->lock = NULL;
request->headers = NULL;
request->state = NEED_FETCH; request->state = NEED_FETCH;
strbuf_init(&request->buffer.buf, 0);
request->next = request_queue_head; request->next = request_queue_head;
request_queue_head = request; request_queue_head = request;
@ -685,12 +688,11 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
} }
obj->flags |= PUSHING; obj->flags |= PUSHING;
request = xmalloc(sizeof(*request)); CALLOC_ARRAY(request, 1);
request->obj = obj; request->obj = obj;
request->url = NULL;
request->lock = lock; request->lock = lock;
request->headers = NULL;
request->state = NEED_PUSH; request->state = NEED_PUSH;
strbuf_init(&request->buffer.buf, 0);
request->next = request_queue_head; request->next = request_queue_head;
request_queue_head = request; request_queue_head = request;
@ -912,6 +914,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
result = XML_Parse(parser, in_buffer.buf, result = XML_Parse(parser, in_buffer.buf,
in_buffer.len, 1); in_buffer.len, 1);
free(ctx.name); free(ctx.name);
free(ctx.cdata);
if (result != XML_STATUS_OK) { if (result != XML_STATUS_OK) {
fprintf(stderr, "XML error: %s\n", fprintf(stderr, "XML error: %s\n",
XML_ErrorString( XML_ErrorString(
@ -1169,6 +1172,7 @@ static void remote_ls(const char *path, int flags,
result = XML_Parse(parser, in_buffer.buf, result = XML_Parse(parser, in_buffer.buf,
in_buffer.len, 1); in_buffer.len, 1);
free(ctx.name); free(ctx.name);
free(ctx.cdata);
if (result != XML_STATUS_OK) { if (result != XML_STATUS_OK) {
fprintf(stderr, "XML error: %s\n", fprintf(stderr, "XML error: %s\n",
@ -1182,6 +1186,7 @@ static void remote_ls(const char *path, int flags,
} }
free(ls.path); free(ls.path);
free(ls.dentry_name);
free(url); free(url);
strbuf_release(&out_buffer.buf); strbuf_release(&out_buffer.buf);
strbuf_release(&in_buffer); strbuf_release(&in_buffer);
@ -1370,9 +1375,13 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock)
} }
while (objects) { while (objects) {
struct object_list *next = objects->next;
if (!(objects->item->flags & UNINTERESTING)) if (!(objects->item->flags & UNINTERESTING))
count += add_send_request(objects->item, lock); count += add_send_request(objects->item, lock);
objects = objects->next;
free(objects);
objects = next;
} }
return count; return count;
@ -1398,6 +1407,7 @@ static int update_remote(const struct object_id *oid, struct remote_lock *lock)
if (start_active_slot(slot)) { if (start_active_slot(slot)) {
run_active_slot(slot); run_active_slot(slot);
strbuf_release(&out_buffer.buf); strbuf_release(&out_buffer.buf);
curl_slist_free_all(dav_headers);
if (results.curl_result != CURLE_OK) { if (results.curl_result != CURLE_OK) {
fprintf(stderr, fprintf(stderr,
"PUT error: curl result=%d, HTTP code=%ld\n", "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)
} }
} else { } else {
strbuf_release(&out_buffer.buf); strbuf_release(&out_buffer.buf);
curl_slist_free_all(dav_headers);
fprintf(stderr, "Unable to start PUT request\n"); fprintf(stderr, "Unable to start PUT request\n");
return 0; return 0;
} }
@ -1516,6 +1527,7 @@ static void update_remote_info_refs(struct remote_lock *lock)
results.curl_result, results.http_code); results.curl_result, results.http_code);
} }
} }
curl_slist_free_all(dav_headers);
} }
strbuf_release(&buffer.buf); strbuf_release(&buffer.buf);
} }
@ -1707,7 +1719,7 @@ int cmd_main(int argc, const char **argv)
int rc = 0; int rc = 0;
int i; int i;
int new_refs; int new_refs;
struct ref *ref, *local_refs; struct ref *ref, *local_refs = NULL;
CALLOC_ARRAY(repo, 1); CALLOC_ARRAY(repo, 1);
@ -1972,6 +1984,7 @@ int cmd_main(int argc, const char **argv)
cleanup: cleanup:
if (info_ref_lock) if (info_ref_lock)
unlock_remote(info_ref_lock); unlock_remote(info_ref_lock);
free(repo->url);
free(repo); free(repo);
http_cleanup(); http_cleanup();
@ -1983,5 +1996,8 @@ int cmd_main(int argc, const char **argv)
request = next_request; request = next_request;
} }
refspec_clear(&rs);
free_refs(local_refs);
return rc; return rc;
} }

View file

@ -74,7 +74,7 @@ static void start_object_request(struct object_request *obj_req)
obj_req->state = ACTIVE; obj_req->state = ACTIVE;
if (!start_active_slot(slot)) { if (!start_active_slot(slot)) {
obj_req->state = ABORTED; obj_req->state = ABORTED;
release_http_object_request(req); release_http_object_request(&req);
return; return;
} }
} }
@ -110,7 +110,7 @@ static void process_object_response(void *callback_data)
if (obj_req->repo->next) { if (obj_req->repo->next) {
obj_req->repo = obj_req->repo =
obj_req->repo->next; obj_req->repo->next;
release_http_object_request(obj_req->req); release_http_object_request(&obj_req->req);
start_object_request(obj_req); start_object_request(obj_req);
return; return;
} }
@ -495,7 +495,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
if (repo_has_object_file(the_repository, &obj_req->oid)) { if (repo_has_object_file(the_repository, &obj_req->oid)) {
if (obj_req->req) if (obj_req->req)
abort_http_object_request(obj_req->req); abort_http_object_request(&obj_req->req);
abort_object_request(obj_req); abort_object_request(obj_req);
return 0; return 0;
} }
@ -543,7 +543,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
strbuf_release(&buf); strbuf_release(&buf);
} }
release_http_object_request(req); release_http_object_request(&obj_req->req);
release_object_request(obj_req); release_object_request(obj_req);
return ret; return ret;
} }
@ -579,8 +579,18 @@ static void cleanup(struct walker *walker)
if (data) { if (data) {
alt = data->alt; alt = data->alt;
while (alt) { while (alt) {
struct packed_git *pack;
alt_next = alt->next; alt_next = alt->next;
pack = alt->packs;
while (pack) {
struct packed_git *pack_next = pack->next;
close_pack(pack);
free(pack);
pack = pack_next;
}
free(alt->base); free(alt->base);
free(alt); free(alt);

16
http.c
View file

@ -800,6 +800,7 @@ static int redact_sensitive_header(struct strbuf *header, size_t offset)
strbuf_setlen(header, sensitive_header - header->buf); strbuf_setlen(header, sensitive_header - header->buf);
strbuf_addbuf(header, &redacted_header); strbuf_addbuf(header, &redacted_header);
strbuf_release(&redacted_header);
ret = 1; ret = 1;
} }
return ret; return ret;
@ -2474,6 +2475,7 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
cleanup: cleanup:
free(url); free(url);
strbuf_release(&buf);
return ret; return ret;
} }
@ -2725,6 +2727,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
* file; also rewind to the beginning of the local file. * file; also rewind to the beginning of the local file.
*/ */
if (prev_read == -1) { if (prev_read == -1) {
git_inflate_end(&freq->stream);
memset(&freq->stream, 0, sizeof(freq->stream)); memset(&freq->stream, 0, sizeof(freq->stream));
git_inflate_init(&freq->stream); git_inflate_init(&freq->stream);
the_hash_algo->init_fn(&freq->c); the_hash_algo->init_fn(&freq->c);
@ -2798,7 +2801,6 @@ int finish_http_object_request(struct http_object_request *freq)
return -1; return -1;
} }
git_inflate_end(&freq->stream);
the_hash_algo->final_oid_fn(&freq->real_oid, &freq->c); the_hash_algo->final_oid_fn(&freq->real_oid, &freq->c);
if (freq->zret != Z_STREAM_END) { if (freq->zret != Z_STREAM_END) {
unlink_or_warn(freq->tmpfile.buf); unlink_or_warn(freq->tmpfile.buf);
@ -2815,15 +2817,17 @@ int finish_http_object_request(struct http_object_request *freq)
return freq->rename; return freq->rename;
} }
void abort_http_object_request(struct http_object_request *freq) void abort_http_object_request(struct http_object_request **freq_p)
{ {
struct http_object_request *freq = *freq_p;
unlink_or_warn(freq->tmpfile.buf); unlink_or_warn(freq->tmpfile.buf);
release_http_object_request(freq); release_http_object_request(freq_p);
} }
void release_http_object_request(struct http_object_request *freq) void release_http_object_request(struct http_object_request **freq_p)
{ {
struct http_object_request *freq = *freq_p;
if (freq->localfile != -1) { if (freq->localfile != -1) {
close(freq->localfile); close(freq->localfile);
freq->localfile = -1; freq->localfile = -1;
@ -2837,4 +2841,8 @@ void release_http_object_request(struct http_object_request *freq)
} }
curl_slist_free_all(freq->headers); curl_slist_free_all(freq->headers);
strbuf_release(&freq->tmpfile); strbuf_release(&freq->tmpfile);
git_inflate_end(&freq->stream);
free(freq);
*freq_p = NULL;
} }

4
http.h
View file

@ -240,8 +240,8 @@ struct http_object_request *new_http_object_request(
const char *base_url, const struct object_id *oid); const char *base_url, const struct object_id *oid);
void process_http_object_request(struct http_object_request *freq); void process_http_object_request(struct http_object_request *freq);
int finish_http_object_request(struct http_object_request *freq); int finish_http_object_request(struct http_object_request *freq);
void abort_http_object_request(struct http_object_request *freq); void abort_http_object_request(struct http_object_request **freq);
void release_http_object_request(struct http_object_request *freq); void release_http_object_request(struct http_object_request **freq);
/* /*
* Instead of using environment variables to determine if curl tracing happens, * Instead of using environment variables to determine if curl tracing happens,

View file

@ -225,7 +225,7 @@ void refspec_clear(struct refspec *rs)
rs->nr = 0; rs->nr = 0;
for (i = 0; i < rs->raw_nr; i++) for (i = 0; i < rs->raw_nr; i++)
free((char *)rs->raw[i]); free(rs->raw[i]);
FREE_AND_NULL(rs->raw); FREE_AND_NULL(rs->raw);
rs->raw_alloc = 0; rs->raw_alloc = 0;
rs->raw_nr = 0; rs->raw_nr = 0;

View file

@ -43,7 +43,7 @@ struct refspec {
int alloc; int alloc;
int nr; int nr;
const char **raw; char **raw;
int raw_alloc; int raw_alloc;
int raw_nr; int raw_nr;

View file

@ -347,7 +347,7 @@ static struct ref *parse_info_refs(struct discovery *heads)
ref->next = refs; ref->next = refs;
refs = ref; refs = ref;
} else { } else {
free(ref); free_one_ref(ref);
} }
return refs; return refs;

View file

@ -2544,7 +2544,7 @@ struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map)
/* /*
* Compare-and-swap * Compare-and-swap
*/ */
static void clear_cas_option(struct push_cas_option *cas) void clear_cas_option(struct push_cas_option *cas)
{ {
int i; int i;

View file

@ -409,6 +409,7 @@ struct push_cas_option {
}; };
int parseopt_push_cas_option(const struct option *, const char *arg, int unset); int parseopt_push_cas_option(const struct option *, const char *arg, int unset);
void clear_cas_option(struct push_cas_option *);
int is_empty_cas(const struct push_cas_option *); int is_empty_cas(const struct push_cas_option *);
void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *); void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);

View file

@ -51,12 +51,11 @@ int unregister_shallow(const struct object_id *oid)
int pos = commit_graft_pos(the_repository, oid); int pos = commit_graft_pos(the_repository, oid);
if (pos < 0) if (pos < 0)
return -1; return -1;
if (pos + 1 < the_repository->parsed_objects->grafts_nr) {
free(the_repository->parsed_objects->grafts[pos]); free(the_repository->parsed_objects->grafts[pos]);
if (pos + 1 < the_repository->parsed_objects->grafts_nr)
MOVE_ARRAY(the_repository->parsed_objects->grafts + pos, MOVE_ARRAY(the_repository->parsed_objects->grafts + pos,
the_repository->parsed_objects->grafts + pos + 1, the_repository->parsed_objects->grafts + pos + 1,
the_repository->parsed_objects->grafts_nr - pos - 1); the_repository->parsed_objects->grafts_nr - pos - 1);
}
the_repository->parsed_objects->grafts_nr--; the_repository->parsed_objects->grafts_nr--;
return 0; return 0;
} }

View file

@ -8,6 +8,7 @@ test_description='Testing multi_ack pack fetching'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
# Test fetch-pack/upload-pack pair. # Test fetch-pack/upload-pack pair.

View file

@ -5,6 +5,7 @@ test_description='fetch/clone from a shallow clone over http'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
. "$TEST_DIRECTORY"/lib-httpd.sh . "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd start_httpd

View file

@ -10,6 +10,7 @@ This test runs various sanity checks on http-push.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
if git http-push > /dev/null 2>&1 || [ $? -eq 128 ] if git http-push > /dev/null 2>&1 || [ $? -eq 128 ]

View file

@ -7,6 +7,7 @@ test_description='test smart pushing over http via http-backend'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
ROOT_PATH="$PWD" ROOT_PATH="$PWD"

View file

@ -5,6 +5,7 @@ test_description='push from/to a shallow clone over http'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
. "$TEST_DIRECTORY"/lib-httpd.sh . "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd start_httpd

View file

@ -4,6 +4,7 @@ test_description='test dumb fetching over http via static file'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
if test_have_prereq !REFFILES if test_have_prereq !REFFILES

View file

@ -5,6 +5,7 @@ test_description="test smart fetching over http via http-backend ($HTTP_PROTO)"
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
. "$TEST_DIRECTORY"/lib-httpd.sh . "$TEST_DIRECTORY"/lib-httpd.sh
test "$HTTP_PROTO" = "HTTP/2" && enable_http2 test "$HTTP_PROTO" = "HTTP/2" && enable_http2

View file

@ -8,6 +8,7 @@ test_description='"git fetch" with negative refspecs.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View file

@ -2,6 +2,7 @@
test_description='test local clone with ambiguous transport' test_description='test local clone with ambiguous transport'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
. "$TEST_DIRECTORY/lib-httpd.sh" . "$TEST_DIRECTORY/lib-httpd.sh"

View file

@ -11,6 +11,7 @@ export GIT_TEST_PROTOCOL_VERSION
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
# Test protocol v1 with 'git://' transport # Test protocol v1 with 'git://' transport

View file

@ -717,8 +717,14 @@ static int fetch_refs(struct transport *transport,
return -1; return -1;
} }
if (!data->get_refs_list_called) if (!data->get_refs_list_called) {
get_refs_list_using_list(transport, 0); /*
* We do not care about the list of refs returned, but only
* that the "list" command was sent.
*/
struct ref *dummy = get_refs_list_using_list(transport, 0);
free_refs(dummy);
}
count = 0; count = 0;
for (i = 0; i < nr_heads; i++) for (i = 0; i < nr_heads; i++)
@ -1023,6 +1029,7 @@ static int push_refs_with_push(struct transport *transport,
if (atomic) { if (atomic) {
reject_atomic_push(remote_refs, mirror); reject_atomic_push(remote_refs, mirror);
string_list_clear(&cas_options, 0); string_list_clear(&cas_options, 0);
strbuf_release(&buf);
return 0; return 0;
} else } else
continue; continue;

View file

@ -414,7 +414,7 @@ static int fetch_refs_via_pack(struct transport *transport,
struct git_transport_data *data = transport->data; struct git_transport_data *data = transport->data;
struct ref *refs = NULL; struct ref *refs = NULL;
struct fetch_pack_args args; struct fetch_pack_args args;
struct ref *refs_tmp = NULL; struct ref *refs_tmp = NULL, **to_fetch_dup = NULL;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.uploadpack = data->options.uploadpack; args.uploadpack = data->options.uploadpack;
@ -477,6 +477,14 @@ static int fetch_refs_via_pack(struct transport *transport,
goto cleanup; goto cleanup;
} }
/*
* Create a shallow copy of `sought` so that we can free all of its entries.
* This is because `fetch_pack()` will modify the array to evict some
* entries, but won't free those.
*/
DUP_ARRAY(to_fetch_dup, to_fetch, nr_heads);
to_fetch = to_fetch_dup;
refs = fetch_pack(&args, data->fd, refs = fetch_pack(&args, data->fd,
refs_tmp ? refs_tmp : transport->remote_refs, refs_tmp ? refs_tmp : transport->remote_refs,
to_fetch, nr_heads, &data->shallow, to_fetch, nr_heads, &data->shallow,
@ -500,6 +508,7 @@ static int fetch_refs_via_pack(struct transport *transport,
ret = -1; ret = -1;
data->conn = NULL; data->conn = NULL;
free(to_fetch_dup);
free_refs(refs_tmp); free_refs(refs_tmp);
free_refs(refs); free_refs(refs);
list_objects_filter_release(&args.filter_options); list_objects_filter_release(&args.filter_options);