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