Commit 5c3d5fb0 by Vicent Martí

Merge pull request #454 from brodie/parsing-fixes

Improvements to tag, commit, and signature parsing
parents a3e23a7c 6f2856f3
...@@ -221,10 +221,10 @@ int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len) ...@@ -221,10 +221,10 @@ int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
} }
/* parse commit message */ /* parse commit message */
while (buffer < buffer_end && *buffer == '\n') while (buffer < buffer_end - 1 && *buffer == '\n')
buffer++; buffer++;
if (buffer < buffer_end) { if (buffer <= buffer_end) {
commit->message = git__strndup(buffer, buffer_end - buffer); commit->message = git__strndup(buffer, buffer_end - buffer);
if (!commit->message) if (!commit->message)
return GIT_ENOMEM; return GIT_ENOMEM;
......
...@@ -279,7 +279,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, ...@@ -279,7 +279,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
if ((name_end = strchr(buffer, '<')) == NULL) if ((name_end = strchr(buffer, '<')) == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Cannot find '<' in signature"); return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Cannot find '<' in signature");
if ((email_end = strchr(buffer, '>')) == NULL) if ((email_end = strchr(name_end, '>')) == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Cannot find '>' in signature"); return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Cannot find '>' in signature");
if (email_end < name_end) if (email_end < name_end)
......
...@@ -122,14 +122,15 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer ...@@ -122,14 +122,15 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer
buffer = search + 1; buffer = search + 1;
tag->tagger = git__malloc(sizeof(git_signature)); tag->tagger = NULL;
if (tag->tagger == NULL) if (*buffer != '\n') {
return GIT_ENOMEM; tag->tagger = git__malloc(sizeof(git_signature));
if (tag->tagger == NULL)
if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n')) != 0) { return GIT_ENOMEM;
free(tag->tag_name);
git_signature_free(tag->tagger); if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n') != 0)) {
return git__rethrow(error, "Failed to parse tag"); return git__rethrow(error, "Failed to parse tag");
}
} }
if( *buffer != '\n' ) if( *buffer != '\n' )
......
[core]
repositoryformatversion = 0
filemode = true
bare = true
logallrefupdates = true
# pack-refs with: peeled
eda9f45a2a98d4c17a09d681d88569fa4ea91755 refs/tags/e90810b
^e90810b8df3e80c413d903f631643c716887138d
be3563ae3f795b2b4353bcce3a527ad0a4f7f644 a65fedf39aefe402d3bb6e24df4d4f5fe4547750
...@@ -412,6 +412,14 @@ BEGIN_TEST(parse1, "parse the signature line in a commit") ...@@ -412,6 +412,14 @@ BEGIN_TEST(parse1, "parse the signature line in a commit")
1234567890, 1234567890,
0); 0);
TEST_SIGNATURE_PASS(
"author A U Thor> <author@example.com> and others 1234567890\n",
"author ",
"A U Thor>",
"author@example.com",
1234567890,
0);
TEST_SIGNATURE_FAIL( TEST_SIGNATURE_FAIL(
"committer Vicent Marti tanoku@gmail.com> 123456 -0100 \n", "committer Vicent Marti tanoku@gmail.com> 123456 -0100 \n",
"committer "); "committer ");
...@@ -560,6 +568,7 @@ static const char *commit_ids[] = { ...@@ -560,6 +568,7 @@ static const char *commit_ids[] = {
"c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */ "c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */
"8496071c1b46c854b31185ea97743be6a8774479", /* 4 */ "8496071c1b46c854b31185ea97743be6a8774479", /* 4 */
"5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */ "5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */
"a65fedf39aefe402d3bb6e24df4d4f5fe4547750", /* 6 */
}; };
BEGIN_TEST(details0, "query the details on a parsed commit") BEGIN_TEST(details0, "query the details on a parsed commit")
...@@ -594,6 +603,7 @@ BEGIN_TEST(details0, "query the details on a parsed commit") ...@@ -594,6 +603,7 @@ BEGIN_TEST(details0, "query the details on a parsed commit")
must_be_true(strcmp(author->email, "schacon@gmail.com") == 0); must_be_true(strcmp(author->email, "schacon@gmail.com") == 0);
must_be_true(strcmp(committer->name, "Scott Chacon") == 0); must_be_true(strcmp(committer->name, "Scott Chacon") == 0);
must_be_true(strcmp(committer->email, "schacon@gmail.com") == 0); must_be_true(strcmp(committer->email, "schacon@gmail.com") == 0);
must_be_true(message != NULL);
must_be_true(strchr(message, '\n') != NULL); must_be_true(strchr(message, '\n') != NULL);
must_be_true(commit_time > 0); must_be_true(commit_time > 0);
must_be_true(parents <= 2); must_be_true(parents <= 2);
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
static const char *tag1_id = "b25fa35b38051e4ae45d4222e795f9df2e43f1d1"; static const char *tag1_id = "b25fa35b38051e4ae45d4222e795f9df2e43f1d1";
static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980"; static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980";
static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d"; static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
static const char *bad_tag_id = "eda9f45a2a98d4c17a09d681d88569fa4ea91755";
static const char *badly_tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
BEGIN_TEST(read0, "read and parse a tag from the repository") BEGIN_TEST(read0, "read and parse a tag from the repository")
git_repository *repo; git_repository *repo;
...@@ -106,6 +108,37 @@ BEGIN_TEST(read2, "list all tag names from the repository matching a specified p ...@@ -106,6 +108,37 @@ BEGIN_TEST(read2, "list all tag names from the repository matching a specified p
git_repository_free(repo); git_repository_free(repo);
END_TEST END_TEST
#define BAD_TAG_REPOSITORY_FOLDER TEST_RESOURCES "/bad_tag.git/"
BEGIN_TEST(read3, "read and parse a tag without a tagger field")
git_repository *repo;
git_tag *bad_tag;
git_commit *commit;
git_oid id, id_commit;
must_pass(git_repository_open(&repo, BAD_TAG_REPOSITORY_FOLDER));
git_oid_fromstr(&id, bad_tag_id);
git_oid_fromstr(&id_commit, badly_tagged_commit);
must_pass(git_tag_lookup(&bad_tag, repo, &id));
must_be_true(bad_tag != NULL);
must_be_true(strcmp(git_tag_name(bad_tag), "e90810b") == 0);
must_be_true(git_oid_cmp(&id, git_tag_id(bad_tag)) == 0);
must_be_true(bad_tag->tagger == NULL);
must_pass(git_tag_target((git_object **)&commit, bad_tag));
must_be_true(commit != NULL);
must_be_true(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
git_tag_close(bad_tag);
git_commit_close(commit);
git_repository_free(repo);
END_TEST
#define TAGGER_NAME "Vicent Marti" #define TAGGER_NAME "Vicent Marti"
#define TAGGER_EMAIL "vicent@github.com" #define TAGGER_EMAIL "vicent@github.com"
...@@ -304,6 +337,7 @@ BEGIN_SUITE(tag) ...@@ -304,6 +337,7 @@ BEGIN_SUITE(tag)
ADD_TEST(read0); ADD_TEST(read0);
ADD_TEST(read1); ADD_TEST(read1);
ADD_TEST(read2); ADD_TEST(read2);
ADD_TEST(read3);
ADD_TEST(write0); ADD_TEST(write0);
ADD_TEST(write2); ADD_TEST(write2);
......
...@@ -70,7 +70,7 @@ END_TEST ...@@ -70,7 +70,7 @@ END_TEST
static const char *head_tracker_sym_ref_name = "head-tracker"; static const char *head_tracker_sym_ref_name = "head-tracker";
static const char *current_head_target = "refs/heads/master"; static const char *current_head_target = "refs/heads/master";
static const char *current_master_tip = "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"; static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
BEGIN_TEST(readsym0, "lookup a symbolic reference") BEGIN_TEST(readsym0, "lookup a symbolic reference")
git_repository *repo; git_repository *repo;
......
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