]> git.proxmox.com Git - libgit2.git/commitdiff
tag: Deploy EINVALIDSPEC usage
authornulltoken <emeric.fermas@gmail.com>
Mon, 12 Nov 2012 14:55:38 +0000 (15:55 +0100)
committernulltoken <emeric.fermas@gmail.com>
Sat, 1 Dec 2012 07:34:28 +0000 (08:34 +0100)
include/git2/tag.h
src/tag.c
tests-clar/object/tag/write.c

index f82a6c9f948495a1213ce6c627406f53dacb94fa..a9773be56eef23177a93a0d984a8c557f930a8fb 100644 (file)
@@ -144,6 +144,10 @@ GIT_EXTERN(const char *) git_tag_message(const git_tag *tag);
  * The message will not be cleaned up. This can be achieved
  * through `git_message_prettify()`.
  *
+ * The tag name will be checked for validity. You must avoid
+ * the characters '~', '^', ':', '\\', '?', '[', and '*', and the
+ * sequences ".." and "@{" which have special meaning to revparse.
+ *
  * @param oid Pointer where to store the OID of the
  * newly created tag. If the tag already exists, this parameter
  * will be the oid of the existing tag, and the function will
@@ -165,7 +169,7 @@ GIT_EXTERN(const char *) git_tag_message(const git_tag *tag);
  *
  * @param force Overwrite existing references
  *
- * @return 0 or an error code
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
  *     A tag object is written to the ODB, and a proper reference
  *     is written in the /refs/tags folder, pointing to it
  */
@@ -200,6 +204,9 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
  * this target object. If `force` is true and a reference
  * already exists with the given name, it'll be replaced.
  *
+ * The tag name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
  * @param oid Pointer where to store the OID of the provided
  * target object. If the tag already exists, this parameter
  * will be filled with the oid of the existing pointed object
@@ -216,7 +223,7 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
  *
  * @param force Overwrite existing references
  *
- * @return 0 or an error code
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
  *     A proper reference is written in the /refs/tags folder,
  * pointing to the provided target object
  */
@@ -230,12 +237,15 @@ GIT_EXTERN(int) git_tag_create_lightweight(
 /**
  * Delete an existing tag reference.
  *
+ * The tag name will be checked for validity.
+ * See `git_tag_create()` for rules about valid names.
+ *
  * @param repo Repository where lives the tag
  *
  * @param tag_name Name of the tag to be deleted;
  * this name is validated for consistency.
  *
- * @return 0 or an error code
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
  */
 GIT_EXTERN(int) git_tag_delete(
        git_repository *repo,
index 606afd657da91fe461b6ac5940a72103dd472f9e..94915ad78858384f5865d4d68b947659580356a0 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -251,7 +251,7 @@ static int git_tag_create__internal(
 
        error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag_name);
        if (error < 0 && error != GIT_ENOTFOUND)
-               return -1;
+               goto cleanup;
 
        /** Ensure the tag name doesn't conflict with an already existing
         *      reference unless overwriting has explictly been requested **/
@@ -269,6 +269,7 @@ static int git_tag_create__internal(
 
        error = git_reference_create(&new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite);
 
+cleanup:
        git_reference_free(new_ref);
        git_buf_free(&ref_name);
        return error;
@@ -384,7 +385,7 @@ int git_tag_delete(git_repository *repo, const char *tag_name)
        git_buf_free(&ref_name);
 
        if (error < 0)
-               return -1;
+               return error;
 
        return git_reference_delete(tag_ref);
 }
index ad6ca76b2198eefab46546b96bb6debd05177c78..eb0ac2897b0fb7947953fc0d753934e946f4b6d5 100644 (file)
@@ -88,7 +88,6 @@ void test_object_tag_write__overwrite(void)
 
        git_object_free(target);
        git_signature_free(tagger);
-
 }
 
 void test_object_tag_write__replace(void)
@@ -190,3 +189,33 @@ void test_object_tag_write__delete(void)
 
        git_reference_free(ref_tag);
 }
+
+void test_object_tag_write__creating_with_an_invalid_name_returns_EINVALIDSPEC(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_OBJ_COMMIT));
+
+       cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
+
+       cl_assert_equal_i(GIT_EINVALIDSPEC,
+               git_tag_create(&tag_id, g_repo,
+                 "Inv@{id", target, tagger, tagger_message, 0)
+       );
+
+       cl_assert_equal_i(GIT_EINVALIDSPEC,
+               git_tag_create_lightweight(&tag_id, g_repo,
+                 "Inv@{id", target, 0)
+       );
+
+       git_object_free(target);
+       git_signature_free(tagger);
+}
+
+void test_object_tag_write__deleting_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+       cl_assert_equal_i(GIT_EINVALIDSPEC, git_tag_delete(g_repo, "Inv@{id"));
+}