Commit 8b2c913a by schu Committed by Vicent Marti

git_signature__parse: make parsing less strict

git_signature__parse used to be very strict about what's a well-formed
signature. Since git_signature__parse is used only when reading already
existing signatures, we should not care about if it's a valid signature
too much but rather show what we got.

Reported-by: nulltoken <emeric.fermas@gmail.com>
Signed-off-by: schu <schu-github@schulog.org>
parent 1bc83ff1
......@@ -153,8 +153,6 @@ static int parse_timezone_offset(const char *buffer, long *offset_out)
int git_signature__parse(git_signature *sig, const char **buffer_out,
const char *buffer_end, const char *header)
{
const size_t header_len = strlen(header);
int name_length, email_length;
const char *buffer = *buffer_out;
const char *line_end, *name_end, *email_end;
......@@ -162,38 +160,40 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
memset(sig, 0x0, sizeof(git_signature));
line_end = memchr(buffer, '\n', buffer_end - buffer);
if (!line_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. No newline found");;
if ((line_end = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. No newline given");
if (buffer + (header_len + 1) > line_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Signature too short");
if (header) {
const size_t header_len = strlen(header);
if (memcmp(buffer, header, header_len) != 0)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Expected prefix '%s' doesn't match actual", header);
if (memcmp(buffer, header, header_len) != 0)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Expected prefix '%s' doesn't match actual", header);
buffer += header_len;
buffer += header_len;
}
/* Parse name */
if ((name_end = strstr(buffer, " <")) == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Can't find e-mail start");
if (buffer > line_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Signature too short");
name_length = name_end - buffer;
if ((name_end = strchr(buffer, '<')) == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Cannot find '<' in signature");
name_length = name_end - 1 - buffer;
if (name_length < 0)
name_length = 0;
sig->name = git__malloc(name_length + 1);
if (sig->name == NULL)
return GIT_ENOMEM;
memcpy(sig->name, buffer, name_length);
sig->name[name_length] = 0;
buffer = name_end + 2;
buffer = name_end + 1;
if (buffer >= line_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Ended unexpectedly");
if (buffer > line_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Signature too short");
/* Parse email */
if ((email_end = strstr(buffer, "> ")) == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Can't find e-mail end");
if ((email_end = strchr(buffer, '>')) == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Cannot find '>' in signature");
email_length = email_end - buffer;
sig->email = git__malloc(email_length + 1);
......@@ -204,10 +204,9 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
sig->email[email_length] = 0;
buffer = email_end + 2;
if (buffer >= line_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Ended unexpectedly");
if (buffer > line_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Signature too short");
/* verify email */
if (strpbrk(sig->email, "><\n") != NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Malformed e-mail");
......@@ -221,7 +220,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
sig->when.offset = offset;
*buffer_out = (line_end + 1);
*buffer_out = line_end + 1;
return GIT_SUCCESS;
}
......
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