Merge pull request #6348 from lya001/fix-invalid-branch-name Fix creation of branches and tags with invalid names
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
diff --git a/src/libgit2/branch.c b/src/libgit2/branch.c
index 2e29af9..2dd7d2b 100644
--- a/src/libgit2/branch.c
+++ b/src/libgit2/branch.c
@@ -53,6 +53,17 @@ static int not_a_local_branch(const char *reference_name)
return -1;
}
+static bool branch_name_is_valid(const char *branch_name)
+{
+ /*
+ * Discourage branch name starting with dash,
+ * https://github.com/git/git/commit/6348624010888b
+ * and discourage HEAD as branch name,
+ * https://github.com/git/git/commit/a625b092cc5994
+ */
+ return branch_name[0] != '-' && git__strcmp(branch_name, "HEAD");
+}
+
static int create_branch(
git_reference **ref_out,
git_repository *repository,
@@ -73,8 +84,8 @@ static int create_branch(
GIT_ASSERT_ARG(ref_out);
GIT_ASSERT_ARG(git_commit_owner(commit) == repository);
- if (!git__strcmp(branch_name, "HEAD")) {
- git_error_set(GIT_ERROR_REFERENCE, "'HEAD' is not a valid branch name");
+ if (!branch_name_is_valid(branch_name)) {
+ git_error_set(GIT_ERROR_REFERENCE, "'%s' is not a valid branch name", branch_name);
error = -1;
goto cleanup;
}
@@ -797,13 +808,7 @@ int git_branch_name_is_valid(int *valid, const char *name)
*valid = 0;
- /*
- * Discourage branch name starting with dash,
- * https://github.com/git/git/commit/6348624010888b
- * and discourage HEAD as branch name,
- * https://github.com/git/git/commit/a625b092cc5994
- */
- if (!name || name[0] == '-' || !git__strcmp(name, "HEAD"))
+ if (!name || !branch_name_is_valid(name))
goto done;
if ((error = git_str_puts(&ref_name, GIT_REFS_HEADS_DIR)) < 0 ||
diff --git a/src/libgit2/tag.c b/src/libgit2/tag.c
index 5734106..792155a 100644
--- a/src/libgit2/tag.c
+++ b/src/libgit2/tag.c
@@ -244,6 +244,15 @@ on_error:
return -1;
}
+static bool tag_name_is_valid(const char *tag_name)
+{
+ /*
+ * Discourage tag name starting with dash,
+ * https://github.com/git/git/commit/4f0accd638b8d2
+ */
+ return tag_name[0] != '-';
+}
+
static int git_tag_create__internal(
git_oid *oid,
git_repository *repo,
@@ -269,6 +278,11 @@ static int git_tag_create__internal(
return -1;
}
+ if (!tag_name_is_valid(tag_name)) {
+ git_error_set(GIT_ERROR_TAG, "'%s' is not a valid tag name", tag_name);
+ return -1;
+ }
+
error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag_name);
if (error < 0 && error != GIT_ENOTFOUND)
goto cleanup;
@@ -542,11 +556,7 @@ int git_tag_name_is_valid(int *valid, const char *name)
*valid = 0;
- /*
- * Discourage tag name starting with dash,
- * https://github.com/git/git/commit/4f0accd638b8d2
- */
- if (!name || name[0] == '-')
+ if (!name || !tag_name_is_valid(name))
goto done;
if ((error = git_str_puts(&ref_name, GIT_REFS_TAGS_DIR)) < 0 ||
diff --git a/tests/libgit2/object/tag/write.c b/tests/libgit2/object/tag/write.c
index 3c1a989..064f328 100644
--- a/tests/libgit2/object/tag/write.c
+++ b/tests/libgit2/object/tag/write.c
@@ -258,3 +258,22 @@ void test_object_tag_write__creating_an_annotation_does_not_create_a_reference(v
create_annotation(&tag_id, "new_tag");
cl_git_fail_with(git_reference_lookup(&tag_ref, g_repo, "refs/tags/new_tag"), GIT_ENOTFOUND);
}
+
+void test_object_tag_write__error_when_create_tag_with_invalid_name(void)
+{
+ git_oid target_id, tag_id;
+ git_signature *tagger;
+ git_object *target;
+
+ git_oid_fromstr(&target_id, tagged_commit);
+ cl_git_pass(git_object_lookup(&target, g_repo, &target_id, GIT_OBJECT_COMMIT));
+ cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+ cl_git_fail(
+ git_tag_create(&tag_id, g_repo,
+ "-dash", target, tagger, tagger_message, 0)
+ );
+
+ git_object_free(target);
+ git_signature_free(tagger);
+}
diff --git a/tests/libgit2/refs/branches/create.c b/tests/libgit2/refs/branches/create.c
index 2fb1166..356bad4 100644
--- a/tests/libgit2/refs/branches/create.c
+++ b/tests/libgit2/refs/branches/create.c
@@ -277,3 +277,11 @@ void test_refs_branches_create__name_vs_namespace_fail(void)
branch = NULL;
}
}
+
+void test_refs_branches_create__error_when_create_branch_with_invalid_name(void)
+{
+ retrieve_known_commit(&target, repo);
+
+ cl_git_fail(git_branch_create(&branch, repo, "HEAD", target, 0));
+ cl_git_fail(git_branch_create(&branch, repo, "-dash", target, 0));
+}