diff --git a/src/remote.c b/src/remote.c index e05ea059f..f2f75bba8 100644 --- a/src/remote.c +++ b/src/remote.c @@ -201,6 +201,30 @@ cleanup: return error; } +static int ensure_remote_name_is_valid(const char *name) +{ + git_buf buf = GIT_BUF_INIT; + git_refspec refspec; + int error = -1; + + if (!name || *name == '\0') + goto cleanup; + + git_buf_printf(&buf, "refs/heads/test:refs/remotes/%s/test", name); + error = git_refspec__parse(&refspec, git_buf_cstr(&buf), true); + + git_buf_free(&buf); + git_refspec__free(&refspec); + +cleanup: + if (error) + giterr_set( + GITERR_CONFIG, + "'%s' is not a valid remote name.", name); + + return error; +} + int git_remote_save(const git_remote *remote) { int error; @@ -208,6 +232,11 @@ int git_remote_save(const git_remote *remote) const char *tagopt = NULL; git_buf buf = GIT_BUF_INIT, value = GIT_BUF_INIT; + assert(remote); + + if (ensure_remote_name_is_valid(remote->name) < 0) + return -1; + if (git_repository_config__weakptr(&config, remote->repo) < 0) return -1; diff --git a/tests-clar/network/remotes.c b/tests-clar/network/remotes.c index 91c3e879d..9fe67d856 100644 --- a/tests-clar/network/remotes.c +++ b/tests-clar/network/remotes.c @@ -10,9 +10,8 @@ static const git_refspec *_refspec; void test_network_remotes__initialize(void) { - cl_fixture_sandbox("testrepo.git"); + _repo = cl_git_sandbox_init("testrepo.git"); - cl_git_pass(git_repository_open(&_repo, "testrepo.git")); cl_git_pass(git_remote_load(&_remote, _repo, "test")); _refspec = git_remote_fetchspec(_remote); @@ -22,8 +21,7 @@ void test_network_remotes__initialize(void) void test_network_remotes__cleanup(void) { git_remote_free(_remote); - git_repository_free(_repo); - cl_fixture_cleanup("testrepo.git"); + cl_git_sandbox_cleanup(); } void test_network_remotes__parsing(void) @@ -73,7 +71,7 @@ void test_network_remotes__parsing_local_path_fails_if_path_not_found(void) void test_network_remotes__supported_transport_methods_are_supported(void) { - cl_assert( git_remote_supported_url("git://github.com/libgit2/libgit2") ); + cl_assert( git_remote_supported_url("git://github.com/libgit2/libgit2") ); } void test_network_remotes__unsupported_transport_methods_are_unsupported(void) @@ -226,6 +224,29 @@ void test_network_remotes__add(void) cl_assert_equal_s(git_remote_url(_remote), "http://github.com/libgit2/libgit2"); } +void test_network_remotes__cannot_add_a_nameless_remote(void) +{ + git_remote *remote; + + cl_git_fail(git_remote_add(&remote, _repo, NULL, "git://github.com/libgit2/libgit2")); + cl_git_fail(git_remote_add(&remote, _repo, "", "git://github.com/libgit2/libgit2")); +} + +void test_network_remotes__cannot_save_a_nameless_remote(void) +{ + git_remote *remote; + + cl_git_pass(git_remote_new(&remote, _repo, NULL, "git://github.com/libgit2/libgit2", NULL)); + + cl_git_fail(git_remote_save(remote)); + git_remote_free(remote); + + cl_git_pass(git_remote_new(&remote, _repo, "", "git://github.com/libgit2/libgit2", NULL)); + + cl_git_fail(git_remote_save(remote)); + git_remote_free(remote); +} + void test_network_remotes__tagopt(void) { const char *opt;