Commit cf7b13f3 by Brodie Rao

tag: avoid a double-free when parsing tags without a tagger field

The v0.99 tag in the Git repo triggers this behavior:

http://git.kernel.org/?p=git/git.git;a=tag;h=d6602ec5194c87b0fc87103ca4d67251c76f233a

Ideally, we'd allow the tag to be instantiated even though the tagger
field is missing, but this at the very least prevents libgit2 from
crashing.

To test this bug, a new repository has been added based on the test
branch in testrepo.git. It contains a "e90810b" tag that looks like
this:

    object e90810b8df3e80c413d903f631643c716887138d
    type commit
    tag e90810b

    This is a very simple tag.
parent 04f78802
......@@ -126,11 +126,8 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer
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);
if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n')) != 0)
return git__rethrow(error, "Failed to parse tag");
}
if( *buffer != '\n' )
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse tag. No new line before message");
......
[core]
repositoryformatversion = 0
filemode = true
bare = true
logallrefupdates = true
# pack-refs with: peeled
eda9f45a2a98d4c17a09d681d88569fa4ea91755 refs/tags/e90810b
^e90810b8df3e80c413d903f631643c716887138d
......@@ -30,6 +30,7 @@
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";
BEGIN_TEST(read0, "read and parse a tag from the repository")
git_repository *repo;
......@@ -106,6 +107,22 @@ 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_oid id;
must_pass(git_repository_open(&repo, BAD_TAG_REPOSITORY_FOLDER));
git_oid_fromstr(&id, bad_tag_id);
must_fail(git_tag_lookup(&bad_tag, repo, &id));
git_repository_free(repo);
END_TEST
#define TAGGER_NAME "Vicent Marti"
#define TAGGER_EMAIL "vicent@github.com"
......@@ -304,6 +321,7 @@ BEGIN_SUITE(tag)
ADD_TEST(read0);
ADD_TEST(read1);
ADD_TEST(read2);
ADD_TEST(read3);
ADD_TEST(write0);
ADD_TEST(write2);
......
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