Skip to content

Commit 6361dea

Browse files
pks-tgitster
authored andcommitted
builtin/clone: fix leaking repo state when cloning with bundle URIs
When cloning with bundle URIs we re-initialize `the_repository` after having fetched the bundle. This causes a bunch of memory leaks though because we do not release its previous state. These leaks can be plugged by calling `repo_clear()` before we call `repo_init()`. But this causes another issue because the remote that we used is tied to the lifetime of the repository's remote state, which would also get released. We thus have to make sure that it does not get free'd under our feet. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a0f2a2f commit 6361dea

File tree

4 files changed

+30
-0
lines changed

4 files changed

+30
-0
lines changed

builtin/clone.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,8 +1403,17 @@ int cmd_clone(int argc,
14031403
* data from the --bundle-uri option.
14041404
*/
14051405
if (bundle_uri) {
1406+
struct remote_state *state;
14061407
int has_heuristic = 0;
14071408

1409+
/*
1410+
* We need to save the remote state as our remote's lifetime is
1411+
* tied to it.
1412+
*/
1413+
state = the_repository->remote_state;
1414+
the_repository->remote_state = NULL;
1415+
repo_clear(the_repository);
1416+
14081417
/* At this point, we need the_repository to match the cloned repo. */
14091418
if (repo_init(the_repository, git_dir, work_tree))
14101419
warning(_("failed to initialize the repo, skipping bundle URI"));
@@ -1413,6 +1422,10 @@ int cmd_clone(int argc,
14131422
bundle_uri);
14141423
else if (has_heuristic)
14151424
git_config_set_gently("fetch.bundleuri", bundle_uri);
1425+
1426+
remote_state_clear(the_repository->remote_state);
1427+
free(the_repository->remote_state);
1428+
the_repository->remote_state = state;
14161429
} else {
14171430
/*
14181431
* Populate transport->got_remote_bundle_uri and
@@ -1422,12 +1435,26 @@ int cmd_clone(int argc,
14221435

14231436
if (transport->bundles &&
14241437
hashmap_get_size(&transport->bundles->bundles)) {
1438+
struct remote_state *state;
1439+
1440+
/*
1441+
* We need to save the remote state as our remote's
1442+
* lifetime is tied to it.
1443+
*/
1444+
state = the_repository->remote_state;
1445+
the_repository->remote_state = NULL;
1446+
repo_clear(the_repository);
1447+
14251448
/* At this point, we need the_repository to match the cloned repo. */
14261449
if (repo_init(the_repository, git_dir, work_tree))
14271450
warning(_("failed to initialize the repo, skipping bundle URI"));
14281451
else if (fetch_bundle_list(the_repository,
14291452
transport->bundles))
14301453
warning(_("failed to fetch advertised bundles"));
1454+
1455+
remote_state_clear(the_repository->remote_state);
1456+
free(the_repository->remote_state);
1457+
the_repository->remote_state = state;
14311458
} else {
14321459
clear_bundle_list(transport->bundles);
14331460
FREE_AND_NULL(transport->bundles);

t/t5730-protocol-v2-bundle-uri-file.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
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
# Test protocol v2 with 'file://' transport

t/t5731-protocol-v2-bundle-uri-git.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
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
# Test protocol v2 with 'git://' transport

t/t5732-protocol-v2-bundle-uri-http.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
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
# Test protocol v2 with 'http://' transport

0 commit comments

Comments
 (0)