The top-level mailinfo() would instead punt when the code in the deeper part of the callchain detects an unrecoverable error in the input. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- mailinfo.c | 30 ++++++++++++++++++++++-------- mailinfo.h | 1 + 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/mailinfo.c b/mailinfo.c index 4fbf38f..9d009fa 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -163,8 +163,10 @@ static void handle_content_type(struct mailinfo *mi, struct strbuf *line) if (slurp_attr(line->buf, "boundary=", boundary)) { strbuf_insert(boundary, 0, "--", 2); if (++mi->content_top >= &mi->content[MAX_BOUNDARIES]) { - fprintf(stderr, "Too many boundaries to handle\n"); - exit(1); + error("Too many boundaries to handle"); + mi->input_error = -1; + mi->content_top = &mi->content[MAX_BOUNDARIES] - 1; + return; } *(mi->content_top) = boundary; boundary = NULL; @@ -355,9 +357,11 @@ static int convert_to_utf8(struct mailinfo *mi, if (same_encoding(mi->metainfo_charset, charset)) return 0; out = reencode_string(line->buf, mi->metainfo_charset, charset); - if (!out) + if (!out) { + mi->input_error = -1; return error("cannot convert from %s to %s", charset, mi->metainfo_charset); + } strbuf_attach(line, out, strlen(out), strlen(out)); return 0; } @@ -367,6 +371,7 @@ static void decode_header(struct mailinfo *mi, struct strbuf *it) char *in, *ep, *cp; struct strbuf outbuf = STRBUF_INIT, *dec; struct strbuf charset_q = STRBUF_INIT, piecebuf = STRBUF_INIT; + int found_error = 1; /* pessimism */ in = it->buf; while (in - it->buf <= it->len && (ep = strstr(in, "=?")) != NULL) { @@ -436,10 +441,14 @@ static void decode_header(struct mailinfo *mi, struct strbuf *it) strbuf_addstr(&outbuf, in); strbuf_reset(it); strbuf_addbuf(it, &outbuf); + found_error = 0; release_return: strbuf_release(&outbuf); strbuf_release(&charset_q); strbuf_release(&piecebuf); + + if (found_error) + mi->input_error = -1; } static int check_header(struct mailinfo *mi, @@ -640,7 +649,7 @@ static int handle_commit_msg(struct mailinfo *mi, struct strbuf *line) /* normalize the log message to UTF-8. */ if (convert_to_utf8(mi, line, mi->charset.buf)) - exit(128); + return 0; /* mi->input_error already set */ if (mi->use_scissors && is_scissors_line(line)) { int i; @@ -783,12 +792,15 @@ again: will fail first. But just in case.. */ if (--mi->content_top < mi->content) { - fprintf(stderr, "Detected mismatched boundaries, " - "can't recover\n"); - exit(1); + error("Detected mismatched boundaries, can't recover"); + mi->input_error = -1; + mi->content_top = mi->content; + return 0; } handle_filter(mi, &newline); strbuf_release(&newline); + if (mi->input_error) + return 0; /* skip to the next boundary */ if (!find_boundary(mi, line)) @@ -873,6 +885,8 @@ static void handle_body(struct mailinfo *mi, struct strbuf *line) handle_filter(mi, line); } + if (mi->input_error) + break; } while (!strbuf_getwholeline(line, mi->input, '\n')); handle_body_out: @@ -966,7 +980,7 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch) handle_info(mi); - return 0; + return mi->input_error; } static int git_mailinfo_config(const char *var, const char *value, void *mi_) diff --git a/mailinfo.h b/mailinfo.h index 27841be..5bf257d 100644 --- a/mailinfo.h +++ b/mailinfo.h @@ -31,6 +31,7 @@ struct mailinfo { struct strbuf **s_hdr_data; struct strbuf log_message; + int input_error; }; extern void setup_mailinfo(struct mailinfo *); -- 2.6.2-383-g144b2e6 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html