summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Martí <tanoku@gmail.com>2011-10-13 12:16:07 -0700
committerVicent Martí <tanoku@gmail.com>2011-10-13 12:16:07 -0700
commit5c3d5fb0182e8c5307dedf9af281fe367a30a16e (patch)
tree784675cb2aa48226532dee707364310b8a5ec556
parenta3e23a7c0a15cbeda434def500acb944a61cc5d4 (diff)
parent6f2856f308918455563413d012e4c4958e57ab40 (diff)
downloadlibgit2-5c3d5fb0182e8c5307dedf9af281fe367a30a16e.tar.gz
Merge pull request #454 from brodie/parsing-fixes
Improvements to tag, commit, and signature parsing
-rw-r--r--src/commit.c4
-rw-r--r--src/signature.c2
-rw-r--r--src/tag.c17
-rw-r--r--tests/resources/bad_tag.git/HEAD1
-rw-r--r--tests/resources/bad_tag.git/config5
-rw-r--r--tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.idxbin0 -> 1268 bytes
-rw-r--r--tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.packbin0 -> 596 bytes
-rw-r--r--tests/resources/bad_tag.git/packed-refs3
-rw-r--r--tests/resources/testrepo.git/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022ccbin0 -> 23 bytes
-rw-r--r--tests/resources/testrepo.git/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe181621
-rw-r--r--tests/resources/testrepo.git/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe45477503
-rw-r--r--tests/resources/testrepo.git/refs/heads/master2
-rw-r--r--tests/t04-commit.c10
-rw-r--r--tests/t08-tag.c34
-rw-r--r--tests/t10-refs.c2
15 files changed, 71 insertions, 13 deletions
diff --git a/src/commit.c b/src/commit.c
index 0ee3854c4..ced457ecc 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -221,10 +221,10 @@ int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
}
/* parse commit message */
- while (buffer < buffer_end && *buffer == '\n')
+ while (buffer < buffer_end - 1 && *buffer == '\n')
buffer++;
- if (buffer < buffer_end) {
+ if (buffer <= buffer_end) {
commit->message = git__strndup(buffer, buffer_end - buffer);
if (!commit->message)
return GIT_ENOMEM;
diff --git a/src/signature.c b/src/signature.c
index ebb56d7ab..388e8d9c9 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -279,7 +279,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
if ((name_end = strchr(buffer, '<')) == NULL)
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");
if (email_end < name_end)
diff --git a/src/tag.c b/src/tag.c
index fc9f8b5e4..ba75104ef 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -122,14 +122,15 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer
buffer = search + 1;
- tag->tagger = git__malloc(sizeof(git_signature));
- if (tag->tagger == NULL)
- return GIT_ENOMEM;
-
- if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n')) != 0) {
- free(tag->tag_name);
- git_signature_free(tag->tagger);
- return git__rethrow(error, "Failed to parse tag");
+ tag->tagger = NULL;
+ if (*buffer != '\n') {
+ tag->tagger = git__malloc(sizeof(git_signature));
+ if (tag->tagger == NULL)
+ return GIT_ENOMEM;
+
+ if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n') != 0)) {
+ return git__rethrow(error, "Failed to parse tag");
+ }
}
if( *buffer != '\n' )
diff --git a/tests/resources/bad_tag.git/HEAD b/tests/resources/bad_tag.git/HEAD
new file mode 100644
index 000000000..cb089cd89
--- /dev/null
+++ b/tests/resources/bad_tag.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/tests/resources/bad_tag.git/config b/tests/resources/bad_tag.git/config
new file mode 100644
index 000000000..2f8958058
--- /dev/null
+++ b/tests/resources/bad_tag.git/config
@@ -0,0 +1,5 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = true
+ logallrefupdates = true
diff --git a/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.idx b/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.idx
new file mode 100644
index 000000000..c404aa15b
--- /dev/null
+++ b/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.idx
Binary files differ
diff --git a/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.pack b/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.pack
new file mode 100644
index 000000000..90eac5032
--- /dev/null
+++ b/tests/resources/bad_tag.git/objects/pack/pack-7a28f4e000a17f49a41d7a79fc2f762a8a7d9164.pack
Binary files differ
diff --git a/tests/resources/bad_tag.git/packed-refs b/tests/resources/bad_tag.git/packed-refs
new file mode 100644
index 000000000..f9fd2fd4a
--- /dev/null
+++ b/tests/resources/bad_tag.git/packed-refs
@@ -0,0 +1,3 @@
+# pack-refs with: peeled
+eda9f45a2a98d4c17a09d681d88569fa4ea91755 refs/tags/e90810b
+^e90810b8df3e80c413d903f631643c716887138d
diff --git a/tests/resources/testrepo.git/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc b/tests/resources/testrepo.git/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc
new file mode 100644
index 000000000..9bb5b623b
--- /dev/null
+++ b/tests/resources/testrepo.git/objects/36/97d64be941a53d4ae8f6a271e4e3fa56b022cc
Binary files differ
diff --git a/tests/resources/testrepo.git/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162 b/tests/resources/testrepo.git/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
new file mode 100644
index 000000000..4cc3f4dff
--- /dev/null
+++ b/tests/resources/testrepo.git/objects/94/4c0f6e4dfa41595e6eb3ceecdb14f50fe18162
@@ -0,0 +1 @@
+x+)JMU044b040031QrutueXlmmAṃJ}G;UTWRQ`6Kǥ^/-*|W3Py`%E\&g|0{Ӎ1X \ No newline at end of file
diff --git a/tests/resources/testrepo.git/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750 b/tests/resources/testrepo.git/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
new file mode 100644
index 000000000..29c8e824d
--- /dev/null
+++ b/tests/resources/testrepo.git/objects/a6/5fedf39aefe402d3bb6e24df4d4f5fe4547750
@@ -0,0 +1,3 @@
+xQ
+!@sBQ" ٱ r{<xƪ
+HlJSer!ZPTe*jUEo^2(XS€EDO<Yj$2s_&} ,}[~p7~<: Zp?1_C0 \ No newline at end of file
diff --git a/tests/resources/testrepo.git/refs/heads/master b/tests/resources/testrepo.git/refs/heads/master
index 9536ad89c..3d8f0a402 100644
--- a/tests/resources/testrepo.git/refs/heads/master
+++ b/tests/resources/testrepo.git/refs/heads/master
@@ -1 +1 @@
-be3563ae3f795b2b4353bcce3a527ad0a4f7f644
+a65fedf39aefe402d3bb6e24df4d4f5fe4547750
diff --git a/tests/t04-commit.c b/tests/t04-commit.c
index 88c7efd81..3fb4d370c 100644
--- a/tests/t04-commit.c
+++ b/tests/t04-commit.c
@@ -412,6 +412,14 @@ BEGIN_TEST(parse1, "parse the signature line in a commit")
1234567890,
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(
"committer Vicent Marti tanoku@gmail.com> 123456 -0100 \n",
"committer ");
@@ -560,6 +568,7 @@ static const char *commit_ids[] = {
"c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */
"8496071c1b46c854b31185ea97743be6a8774479", /* 4 */
"5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", /* 6 */
};
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(committer->name, "Scott Chacon") == 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(commit_time > 0);
must_be_true(parents <= 2);
diff --git a/tests/t08-tag.c b/tests/t08-tag.c
index b0d4af87b..216fb9dfc 100644
--- a/tests/t08-tag.c
+++ b/tests/t08-tag.c
@@ -30,6 +30,8 @@
static const char *tag1_id = "b25fa35b38051e4ae45d4222e795f9df2e43f1d1";
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";
BEGIN_TEST(read0, "read and parse a tag from the repository")
git_repository *repo;
@@ -106,6 +108,37 @@ BEGIN_TEST(read2, "list all tag names from the repository matching a specified p
git_repository_free(repo);
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_EMAIL "vicent@github.com"
@@ -304,6 +337,7 @@ BEGIN_SUITE(tag)
ADD_TEST(read0);
ADD_TEST(read1);
ADD_TEST(read2);
+ ADD_TEST(read3);
ADD_TEST(write0);
ADD_TEST(write2);
diff --git a/tests/t10-refs.c b/tests/t10-refs.c
index 67034155d..1b3e0a3aa 100644
--- a/tests/t10-refs.c
+++ b/tests/t10-refs.c
@@ -70,7 +70,7 @@ END_TEST
static const char *head_tracker_sym_ref_name = "head-tracker";
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")
git_repository *repo;