From eb39284babba00c763911b93aa9219803612b965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 25 Apr 2016 12:16:05 +0200 Subject: tag: ignore extra header fields 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. --- src/tag.c | 10 ++++++++-- tests/object/tag/read.c | 37 +++++++++++++++++++++++++++++++++++++ 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 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); +} -- cgit v1.2.1