From edbaa63a7c3c319621b773bad5851b2b48c9d175 Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Tue, 25 Jun 2013 09:04:04 +0200 Subject: [PATCH 1/2] Unbreak git_remote_ls on a local transport after disconnecting. --- src/transports/local.c | 27 +++++++++++++++------------ tests-clar/network/remote/local.c | 12 ++++++++++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/transports/local.c b/src/transports/local.c index 550060958..2a85e95e7 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -119,15 +119,24 @@ on_error: static int store_refs(transport_local *t) { - unsigned int i; + size_t i; + git_remote_head *head; git_strarray ref_names = {0}; assert(t); - if (git_reference_list(&ref_names, t->repo) < 0 || - git_vector_init(&t->refs, ref_names.count, NULL) < 0) + if (git_reference_list(&ref_names, t->repo) < 0) goto on_error; + /* Clear all heads we might have fetched in a previous connect */ + git_vector_foreach(&t->refs, i, head) { + git__free(head->name); + git__free(head); + } + + /* Clear the vector so we can reuse it */ + git_vector_clear(&t->refs); + /* Sort the references first */ git__tsort((void **)ref_names.strings, ref_names.count, &git__strcmp_cb); @@ -571,8 +580,6 @@ static void local_cancel(git_transport *transport) static int local_close(git_transport *transport) { transport_local *t = (transport_local *)transport; - size_t i; - git_remote_head *head; t->connected = 0; @@ -586,13 +593,6 @@ static int local_close(git_transport *transport) t->url = NULL; } - git_vector_foreach(&t->refs, i, head) { - git__free(head->name); - git__free(head); - } - - git_vector_free(&t->refs); - return 0; } @@ -600,6 +600,8 @@ static void local_free(git_transport *transport) { transport_local *t = (transport_local *)transport; + git_vector_free(&t->refs); + /* Close the transport, if it's still open. */ local_close(transport); @@ -632,6 +634,7 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param) t->parent.read_flags = local_read_flags; t->parent.cancel = local_cancel; + git_vector_init(&t->refs, 0, NULL); t->owner = owner; *out = (git_transport *) t; diff --git a/tests-clar/network/remote/local.c b/tests-clar/network/remote/local.c index 3cb8a25d6..d5d75fdc6 100644 --- a/tests-clar/network/remote/local.c +++ b/tests-clar/network/remote/local.c @@ -75,6 +75,18 @@ void test_network_remote_local__retrieve_advertised_references(void) cl_assert_equal_i(how_many_refs, 28); } +void test_network_remote_local__retrieve_advertised_references_after_disconnect(void) +{ + int how_many_refs = 0; + + connect_to_local_repository(cl_fixture("testrepo.git")); + git_remote_disconnect(remote); + + cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs)); + + cl_assert_equal_i(how_many_refs, 28); +} + void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void) { int how_many_refs = 0; From 9728cfde5f3685cb11302560a67754104d618ea2 Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Tue, 25 Jun 2013 11:17:55 +0300 Subject: [PATCH 2/2] Make sure we don't leak memory again. --- src/transports/local.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/transports/local.c b/src/transports/local.c index 2a85e95e7..a9da8146c 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -599,6 +599,13 @@ static int local_close(git_transport *transport) static void local_free(git_transport *transport) { transport_local *t = (transport_local *)transport; + size_t i; + git_remote_head *head; + + git_vector_foreach(&t->refs, i, head) { + git__free(head->name); + git__free(head); + } git_vector_free(&t->refs);