diff options
author | nulltoken <emeric.fermas@gmail.com> | 2012-12-24 15:59:01 +0100 |
---|---|---|
committer | nulltoken <emeric.fermas@gmail.com> | 2012-12-24 18:18:31 +0100 |
commit | f19304d2653cdc829f549283b3fb4e2e4d9b06ce (patch) | |
tree | 4fc76ebee6245394a589773cbfda71ba9f207347 | |
parent | ae35aa07082968e00b9b77173c622482ea02db5d (diff) | |
download | libgit2-f19304d2653cdc829f549283b3fb4e2e4d9b06ce.tar.gz |
remote: Prevent create() from blindly overwriting
-rw-r--r-- | include/git2/remote.h | 2 | ||||
-rw-r--r-- | src/remote.c | 10 | ||||
-rw-r--r-- | tests-clar/network/remotes.c | 11 |
3 files changed, 17 insertions, 6 deletions
diff --git a/include/git2/remote.h b/include/git2/remote.h index 0be30cd02..29bda796d 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -41,7 +41,7 @@ typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, voi * @param repo the repository in which to create the remote * @param name the remote's name * @param url the remote's url - * @return 0, GIT_EINVALIDSPEC or an error code + * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code */ GIT_EXTERN(int) git_remote_create( git_remote **out, diff --git a/src/remote.c b/src/remote.c index ba7eeed82..5384db622 100644 --- a/src/remote.c +++ b/src/remote.c @@ -106,11 +106,6 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n GITERR_CHECK_ALLOC(remote->url); if (name != NULL) { - if ((error = ensure_remote_name_is_valid(name)) < 0) { - error = GIT_EINVALIDSPEC; - goto on_error; - } - remote->name = git__strdup(name); GITERR_CHECK_ALLOC(remote->name); } @@ -135,6 +130,8 @@ on_error: return error; } +extern int ensure_remote_doesnot_exist(git_repository *repo, const char *name); + int git_remote_create(git_remote **out, git_repository *repo, const char *name, const char *url) { git_buf buf = GIT_BUF_INIT; @@ -143,6 +140,9 @@ int git_remote_create(git_remote **out, git_repository *repo, const char *name, if ((error = ensure_remote_name_is_valid(name)) < 0) return error; + if ((error = ensure_remote_doesnot_exist(repo, name)) < 0) + return error; + if (git_buf_printf(&buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0) return -1; diff --git a/tests-clar/network/remotes.c b/tests-clar/network/remotes.c index 26558f22b..79761c884 100644 --- a/tests-clar/network/remotes.c +++ b/tests-clar/network/remotes.c @@ -346,3 +346,14 @@ void test_network_remotes__check_structure_version(void) err = giterr_last(); cl_assert_equal_i(GITERR_INVALID, err->klass); } + +void test_network_remotes__cannot_create_a_remote_which_name_conflicts_with_an_existing_remote(void) +{ + git_remote *remote = NULL; + + cl_assert_equal_i( + GIT_EEXISTS, + git_remote_create(&remote, _repo, "test", "git://github.com/libgit2/libgit2")); + + cl_assert_equal_p(remote, NULL); +} |