Commit 6bb9fea1 by Erik van Zijst

tags: Fixed the tag parser to correctly treat the message field as optional.

This fix makes libgit2 capable of parsing annotated tag objects that lack
the optional message/description field.
Previously, libgit2 treated this field as mandatory and raised a tag_error on
such tags. However, the message field is optional.

An example of such a tag is refs/tags/v2.6.16.31-rc1 in Linux:

$ git cat-file tag refs/tags/v2.6.16.31-rc1
object afaa018cefb6af63befef1df7d8febaae904434f
type commit
tag v2.6.16.31-rc1
tagger Adrian Bunk <bunk@stusta.de> 1162716505 +0100
$
parent e30c052c
......@@ -139,16 +139,19 @@ int git_tag__parse_buffer(git_tag *tag, const char *buffer, size_t length)
return -1;
}
if( *buffer != '\n' )
return tag_error("No new line before message");
tag->message = NULL;
if (buffer < buffer_end) {
if( *buffer != '\n' )
return tag_error("No new line before message");
text_len = buffer_end - ++buffer;
text_len = buffer_end - ++buffer;
tag->message = git__malloc(text_len + 1);
GITERR_CHECK_ALLOC(tag->message);
tag->message = git__malloc(text_len + 1);
GITERR_CHECK_ALLOC(tag->message);
memcpy(tag->message, buffer, text_len);
tag->message[text_len] = '\0';
memcpy(tag->message, buffer, text_len);
tag->message[text_len] = '\0';
}
return 0;
}
......
......@@ -7,6 +7,8 @@ static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980";
static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
static const char *bad_tag_id = "eda9f45a2a98d4c17a09d681d88569fa4ea91755";
static const char *badly_tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
static const char *short_tag_id = "5da7760512a953e3c7c4e47e4392c7a4338fb729";
static const char *short_tagged_commit = "4a5ed60bafcf4638b7c8356bd4ce1916bfede93c";
static git_repository *g_repo;
......@@ -83,3 +85,34 @@ void test_object_tag_read__parse_without_tagger(void)
git_commit_free(commit);
git_repository_free(bad_tag_repo);
}
void test_object_tag_read__parse_without_message(void)
{
// read and parse a tag without a message field
git_repository *short_tag_repo;
git_tag *short_tag;
git_commit *commit;
git_oid id, id_commit;
// TODO: This is a little messy
cl_git_pass(git_repository_open(&short_tag_repo, cl_fixture("short_tag.git")));
git_oid_fromstr(&id, short_tag_id);
git_oid_fromstr(&id_commit, short_tagged_commit);
cl_git_pass(git_tag_lookup(&short_tag, short_tag_repo, &id));
cl_assert(short_tag != NULL);
cl_assert_equal_s(git_tag_name(short_tag), "no_description");
cl_assert(git_oid_cmp(&id, git_tag_id(short_tag)) == 0);
cl_assert(short_tag->message == NULL);
cl_git_pass(git_tag_target((git_object **)&commit, short_tag));
cl_assert(commit != NULL);
cl_assert(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
git_tag_free(short_tag);
git_commit_free(commit);
git_repository_free(short_tag_repo);
}
[core]
repositoryformatversion = 0
filemode = true
bare = true
logallrefupdates = true
5da7760512a953e3c7c4e47e4392c7a4338fb729 refs/tags/no_description
4a5ed60bafcf4638b7c8356bd4ce1916bfede93c
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment