summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2014-03-11 16:41:11 -0700
committerRussell Belfer <rb@github.com>2014-03-11 16:41:11 -0700
commit680f306d361609a818e8d9ebb382286be084263c (patch)
tree35095a63ca4686f8213e9793b5071ff1dd928bb6 /src
parent676a34a33d9ef18163c3a33bac60083de471144f (diff)
downloadlibgit2-rb/warnings-for-commit-headers.tar.gz
Warnings that default to being errorsrb/warnings-for-commit-headers
This is a try at extending the warning API to include warnings that would be errors unless the user callback decides to demote them to warnings. This allows for relaxed parsing logic that will default to strict behavior but can continue if possible.
Diffstat (limited to 'src')
-rw-r--r--src/signature.c39
-rw-r--r--src/warning.c16
-rw-r--r--src/warning.h13
3 files changed, 52 insertions, 16 deletions
diff --git a/src/signature.c b/src/signature.c
index a513b0e65..a57d9c4ac 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -177,17 +177,38 @@ int git_signature__parse(
}
email_start = git__memrchr(buffer, '<', buffer_end - buffer);
- email_end = git__memrchr(buffer, '>', buffer_end - buffer);
-
- if (!email_start || !email_end || email_end <= email_start)
- return signature_error("malformed e-mail");
+ if (!email_start) {
+ if (git_warn_invalid_data(
+ GIT_WARNING_INVALID_DATA__SIGNATURE_EMAIL_MISSING, -1,
+ buffer, (int)(buffer_end - buffer),
+ "missing signature %semail", header) < 0)
+ return signature_error("missing e-mail");
+
+ /* just stop now with everything as name */
+ sig->name = extract_trimmed(buffer, buffer_end - buffer);
+ sig->email = git__strdup("");
+ *buffer_out = buffer_end + 1;
+ return 0;
+ }
+ sig->name = extract_trimmed(buffer, email_start - buffer);
email_start += 1;
- sig->name = extract_trimmed(buffer, email_start - buffer - 1);
- sig->email = extract_trimmed(email_start, email_end - email_start);
+
+ email_end = git__memrchr(email_start, '>', buffer_end - email_start);
+ if (!email_end) {
+ if (git_warn_invalid_data(
+ GIT_WARNING_INVALID_DATA__SIGNATURE_EMAIL_UNTERMINATED, -1,
+ email_start, (int)(buffer_end - email_start),
+ "unterminated signature %semail", header) < 0)
+ return signature_error("malformed e-mail");
+
+ sig->email = extract_trimmed(email_start, buffer_end - email_start);
+ } else {
+ sig->email = extract_trimmed(email_start, email_end - email_start);
+ }
/* Do we even have a time at the end of the signature? */
- if (email_end + 2 < buffer_end) {
+ if (email_end != NULL && email_end + 2 < buffer_end) {
const char *time_start = email_end + 2;
const char *time_end;
@@ -200,7 +221,7 @@ int git_signature__parse(
/* warn (and return error if requested) */
if (git_warn_invalid_data(
- GIT_WARNING_INVALID_DATA__SIGNATURE_TIMESTAMP,
+ GIT_WARNING_INVALID_DATA__SIGNATURE_TIMESTAMP, 0,
time_start, (int)(time_end - time_start),
"invalid signature %stimestamp", header) < 0)
return signature_error("invalid Unix timestamp");
@@ -224,7 +245,7 @@ int git_signature__parse(
/* warn (and return error if requested) */
if (git_warn_invalid_data(
- GIT_WARNING_INVALID_DATA__SIGNATURE_TIMEZONE,
+ GIT_WARNING_INVALID_DATA__SIGNATURE_TIMEZONE, 0,
tz_start, (int)(tz_end - tz_start),
"invalid timezone in signature %s", header) < 0)
return signature_error("invalid timezone");
diff --git a/src/warning.c b/src/warning.c
index 1066c2c8d..b0bc7c03d 100644
--- a/src/warning.c
+++ b/src/warning.c
@@ -19,18 +19,18 @@ void git_warning_set_callback(git_warning_callback cb, void *payload)
}
static int git_warning__send(
- git_warning *warning, const char *fmt, va_list ap)
+ git_warning *warning, int default_rval, const char *fmt, va_list ap)
{
int error = 0;
git_buf buf = GIT_BUF_INIT;
git_warning_callback cb = _warning_cb;
if (!cb)
- return 0;
+ return default_rval;
if (!(error = git_buf_vprintf(&buf, fmt, ap))) {
warning->message = git_buf_cstr(&buf);
- error = cb(warning, _warning_payload);
+ error = cb(warning, default_rval, _warning_payload);
}
git_buf_free(&buf);
@@ -40,6 +40,7 @@ static int git_warning__send(
int git_warn(
git_warning_t type,
+ int default_rval,
const char *fmt,
...)
{
@@ -48,12 +49,12 @@ int git_warn(
git_warning warning;
if (!_warning_cb)
- return 0;
+ return default_rval;
warning.type = type;
va_start(ap, fmt);
- error = git_warning__send(&warning, fmt, ap);
+ error = git_warning__send(&warning, default_rval, fmt, ap);
va_end(ap);
return error;
@@ -61,6 +62,7 @@ int git_warn(
int git_warn_invalid_data(
git_warning_t type,
+ int default_rval,
const char *data,
int datalen,
const char *fmt,
@@ -71,7 +73,7 @@ int git_warn_invalid_data(
git_warning_invalid_data warning;
if (!_warning_cb)
- return 0;
+ return default_rval;
warning.base.type = type;
warning.invalid_data = git__strndup(data, datalen);
@@ -79,7 +81,7 @@ int git_warn_invalid_data(
warning.invalid_data_len = datalen;
va_start(ap, fmt);
- error = git_warning__send((git_warning *)&warning, fmt, ap);
+ error = git_warning__send((git_warning *)&warning, default_rval, fmt, ap);
va_end(ap);
git__free((char *)warning.invalid_data);
diff --git a/src/warning.h b/src/warning.h
index 6d25783f4..8c14e2869 100644
--- a/src/warning.h
+++ b/src/warning.h
@@ -10,13 +10,26 @@
#include "common.h"
#include "git2/sys/warning.h"
+/**
+ * Use this to raise a warning
+ *
+ * @param warning A git_warning_t code from include/git2/sys/warning.h
+ * @param default_rval Default return value (i.e. error code or zero)
+ * @param fmt Printf-style format string for warning message
+ * @return 0 to continue, less than 0 to raise error
+ */
int git_warn(
git_warning_t warning,
+ int default_rval,
const char *fmt,
...);
+/**
+ * Raise a warning about invalid data, via a git_warning_invalid_data struct
+ */
int git_warn_invalid_data(
git_warning_t warning,
+ int default_rval,
const char *data,
int datalen,
const char *fmt,