mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-27 14:02:50 +00:00
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>
This commit is contained in:
parent
1bc83ff14f
commit
8b2c913acb
@ -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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
sig->when.offset = offset;
|
sig->when.offset = offset;
|
||||||
|
|
||||||
*buffer_out = (line_end + 1);
|
*buffer_out = line_end + 1;
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user