diff options
author | David Glesser <glesserd@ensimag.fr> | 2011-05-31 18:38:59 +0200 |
---|---|---|
committer | David Glesser <glesserd@ensimag.fr> | 2011-05-31 18:38:59 +0200 |
commit | fbfc7580226c4f0fdf2bcc0df21add033c649681 (patch) | |
tree | aa84b8c4391e3cf889d855463c3bb0ae22706f30 /src/signature.c | |
parent | 4191d529245084fa92e869aadda72dd740403d3a (diff) | |
download | libgit2-fbfc7580226c4f0fdf2bcc0df21add033c649681.tar.gz |
Fix tag and signature parsing
Before this commit, malformed tag and signature were considered as
valid by the parser. See the test t3800-mktag.sh of git to see example
of malformed tag and signature.
Diffstat (limited to 'src/signature.c')
-rw-r--r-- | src/signature.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/signature.c b/src/signature.c index 683264108..0527eaa5b 100644 --- a/src/signature.c +++ b/src/signature.c @@ -107,6 +107,7 @@ static int parse_timezone_offset(const char *buffer, long *offset_out) const char *offset_start; const char *offset_end; + //we are sure that *buffer == ' ' offset_start = buffer + 1; if (*offset_start == '\n') { @@ -117,17 +118,23 @@ static int parse_timezone_offset(const char *buffer, long *offset_out) if (offset_start[0] != '-' && offset_start[0] != '+') return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. It doesn't start with '+' or '-'"); + if (offset_start[1] < '0' || offset_start[1] > '9') + return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. + if (git__strtol32(&dec_offset, offset_start + 1, &offset_end, 10) < GIT_SUCCESS) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. It isn't a number"); if (offset_end - offset_start != 5) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. Invalid length"); + if (dec_offset > 1400) + return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. Value too large"); + hours = dec_offset / 100; mins = dec_offset % 100; if (hours > 14) // see http://www.worldtimezone.com/faq.html - return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. Hour value too large");; + return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. Hour value too large"); if (mins > 59) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse TZ offset. Minute value too large"); @@ -168,23 +175,26 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, buffer += header_len; /* Parse name */ - if ((name_end = memchr(buffer, '<', buffer_end - buffer)) == NULL) + if ((name_end = strstr(buffer, " <")) == NULL) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Can't find e-mail start"); - name_length = name_end - buffer - 1; + name_length = name_end - buffer; + if (name_length <= 0) + return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Missing tagger name"); + 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 + 1; + buffer = name_end + 2; if (buffer >= line_end) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Ended unexpectedly"); /* Parse email */ - if ((email_end = memchr(buffer, '>', buffer_end - buffer)) == NULL) + if ((email_end = strstr(buffer, "> ")) == NULL) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Can't find e-mail end"); email_length = email_end - buffer; @@ -194,11 +204,15 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, memcpy(sig->email, buffer, email_length); sig->email[email_length] = 0; - buffer = email_end + 1; + buffer = email_end + 2; if (buffer >= line_end) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Ended unexpectedly"); + /* verify email */ + if (strpbrk(sig->email, "><\n ") != NULL) + return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Malformed e-mail"); + if (git__strtol32(&time, buffer, &buffer, 10) < GIT_SUCCESS) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Timestamp isn't a number"); |