summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2016-04-25 12:16:05 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2016-04-25 12:18:32 +0200
commiteb39284babba00c763911b93aa9219803612b965 (patch)
treef34949b3e3a53b513c8cffb57d971a83dcda78a4
parent512bd2c78f700186f92271e502b123ea27f75614 (diff)
downloadlibgit2-cmn/silly-tags.tar.gz
tag: ignore extra header fieldscmn/silly-tags
While no extra header fields are defined for tags, git accepts them by ignoring them and continuing the search for the message. There are a few tags like this in the wild which git parses just fine, so we should do the same.
-rw-r--r--src/tag.c10
-rw-r--r--tests/object/tag/read.c37
2 files changed, 45 insertions, 2 deletions
diff --git a/src/tag.c b/src/tag.c
index c4bce1f22..fe840fe82 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -137,8 +137,14 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
tag->message = NULL;
if (buffer < buffer_end) {
- if( *buffer != '\n' )
- return tag_error("No new line before message");
+ /* If we're not at the end of the header, search for it */
+ if( *buffer != '\n' ) {
+ search = strstr(buffer, "\n\n");
+ if (search)
+ buffer = search + 1;
+ else
+ return tag_error("tag contains no message");
+ }
text_len = buffer_end - ++buffer;
diff --git a/tests/object/tag/read.c b/tests/object/tag/read.c
index c9787a413..8f28afd54 100644
--- a/tests/object/tag/read.c
+++ b/tests/object/tag/read.c
@@ -140,3 +140,40 @@ void test_object_tag_read__without_tagger_nor_message(void)
git_tag_free(tag);
git_repository_free(repo);
}
+
+static const char *silly_tag = "object c054ccaefbf2da31c3b19178f9e3ef20a3867924\n\
+type commit\n\
+tag v1_0_1\n\
+tagger Jamis Buck <jamis@37signals.com> 1107717917\n\
+diff --git a/lib/sqlite3/version.rb b/lib/sqlite3/version.rb\n\
+index 0b3bf69..4ee8fc2 100644\n\
+--- a/lib/sqlite3/version.rb\n\
++++ b/lib/sqlite3/version.rb\n\
+@@ -36,7 +36,7 @@ module SQLite3\n\
+ \n\
+ MAJOR = 1\n\
+ MINOR = 0\n\
+- TINY = 0\n\
++ TINY = 1\n\
+ \n\
+ STRING = [ MAJOR, MINOR, TINY ].join( \".\" )\n\
+ \n\
+ -0600\n\
+\n\
+v1_0_1 release\n";
+
+void test_object_tag_read__extra_header_fields(void)
+{
+ git_tag *tag;
+ git_odb *odb;
+ git_oid id;
+
+ cl_git_pass(git_repository_odb__weakptr(&odb, g_repo));
+
+ cl_git_pass(git_odb_write(&id, odb, silly_tag, strlen(silly_tag), GIT_OBJ_TAG));
+ cl_git_pass(git_tag_lookup(&tag, g_repo, &id));
+
+ cl_assert_equal_s("v1_0_1 release\n", git_tag_message(tag));
+
+ git_tag_free(tag);
+}