Skip to content

Commit 3c8a860

Browse files
authored
Merge pull request libgit2#6348 from lya001/fix-invalid-branch-name
Fix creation of branches and tags with invalid names
2 parents b70dbaa + be08ef7 commit 3c8a860

File tree

4 files changed

+56
-14
lines changed

4 files changed

+56
-14
lines changed

src/libgit2/branch.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ static int not_a_local_branch(const char *reference_name)
5353
return -1;
5454
}
5555

56+
static bool branch_name_is_valid(const char *branch_name)
57+
{
58+
/*
59+
* Discourage branch name starting with dash,
60+
* https://github.com/git/git/commit/6348624010888b
61+
* and discourage HEAD as branch name,
62+
* https://github.com/git/git/commit/a625b092cc5994
63+
*/
64+
return branch_name[0] != '-' && git__strcmp(branch_name, "HEAD");
65+
}
66+
5667
static int create_branch(
5768
git_reference **ref_out,
5869
git_repository *repository,
@@ -73,8 +84,8 @@ static int create_branch(
7384
GIT_ASSERT_ARG(ref_out);
7485
GIT_ASSERT_ARG(git_commit_owner(commit) == repository);
7586

76-
if (!git__strcmp(branch_name, "HEAD")) {
77-
git_error_set(GIT_ERROR_REFERENCE, "'HEAD' is not a valid branch name");
87+
if (!branch_name_is_valid(branch_name)) {
88+
git_error_set(GIT_ERROR_REFERENCE, "'%s' is not a valid branch name", branch_name);
7889
error = -1;
7990
goto cleanup;
8091
}
@@ -797,13 +808,7 @@ int git_branch_name_is_valid(int *valid, const char *name)
797808

798809
*valid = 0;
799810

800-
/*
801-
* Discourage branch name starting with dash,
802-
* https://github.com/git/git/commit/6348624010888b
803-
* and discourage HEAD as branch name,
804-
* https://github.com/git/git/commit/a625b092cc5994
805-
*/
806-
if (!name || name[0] == '-' || !git__strcmp(name, "HEAD"))
811+
if (!name || !branch_name_is_valid(name))
807812
goto done;
808813

809814
if ((error = git_str_puts(&ref_name, GIT_REFS_HEADS_DIR)) < 0 ||

src/libgit2/tag.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,15 @@ static int write_tag_annotation(
244244
return -1;
245245
}
246246

247+
static bool tag_name_is_valid(const char *tag_name)
248+
{
249+
/*
250+
* Discourage tag name starting with dash,
251+
* https://github.com/git/git/commit/4f0accd638b8d2
252+
*/
253+
return tag_name[0] != '-';
254+
}
255+
247256
static int git_tag_create__internal(
248257
git_oid *oid,
249258
git_repository *repo,
@@ -269,6 +278,11 @@ static int git_tag_create__internal(
269278
return -1;
270279
}
271280

281+
if (!tag_name_is_valid(tag_name)) {
282+
git_error_set(GIT_ERROR_TAG, "'%s' is not a valid tag name", tag_name);
283+
return -1;
284+
}
285+
272286
error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag_name);
273287
if (error < 0 && error != GIT_ENOTFOUND)
274288
goto cleanup;
@@ -542,11 +556,7 @@ int git_tag_name_is_valid(int *valid, const char *name)
542556

543557
*valid = 0;
544558

545-
/*
546-
* Discourage tag name starting with dash,
547-
* https://github.com/git/git/commit/4f0accd638b8d2
548-
*/
549-
if (!name || name[0] == '-')
559+
if (!name || !tag_name_is_valid(name))
550560
goto done;
551561

552562
if ((error = git_str_puts(&ref_name, GIT_REFS_TAGS_DIR)) < 0 ||

tests/libgit2/object/tag/write.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,22 @@ void test_object_tag_write__creating_an_annotation_does_not_create_a_reference(v
258258
create_annotation(&tag_id, "new_tag");
259259
cl_git_fail_with(git_reference_lookup(&tag_ref, g_repo, "refs/tags/new_tag"), GIT_ENOTFOUND);
260260
}
261+
262+
void test_object_tag_write__error_when_create_tag_with_invalid_name(void)
263+
{
264+
git_oid target_id, tag_id;
265+
git_signature *tagger;
266+
git_object *target;
267+
268+
git_oid_fromstr(&target_id, tagged_commit);
269+
cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
270+
cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
271+
272+
cl_git_fail(
273+
git_tag_create(&tag_id, g_repo,
274+
"-dash", target, tagger, tagger_message, 0)
275+
);
276+
277+
git_object_free(target);
278+
git_signature_free(tagger);
279+
}

tests/libgit2/refs/branches/create.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,11 @@ void test_refs_branches_create__name_vs_namespace_fail(void)
277277
branch = NULL;
278278
}
279279
}
280+
281+
void test_refs_branches_create__error_when_create_branch_with_invalid_name(void)
282+
{
283+
retrieve_known_commit(&target, repo);
284+
285+
cl_git_fail(git_branch_create(&branch, repo, "HEAD", target, 0));
286+
cl_git_fail(git_branch_create(&branch, repo, "-dash", target, 0));
287+
}

0 commit comments

Comments
 (0)