From: Junio C Hamano Date: Tue, 13 Feb 2018 21:39:14 +0000 (-0800) Subject: Merge branch 'jc/mailinfo-cleanup-fix' X-Git-Tag: v2.17.0-rc0~114 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/46e915c42bdef79caf65ebdd26ee39aa0c011ebc?ds=inline;hp=-c Merge branch 'jc/mailinfo-cleanup-fix' Corner case bugfix. * jc/mailinfo-cleanup-fix: mailinfo: avoid segfault when can't open files --- 46e915c42bdef79caf65ebdd26ee39aa0c011ebc diff --combined mailinfo.c index a89db22ab0,36ec927b9e..d04142ccc7 --- a/mailinfo.c +++ b/mailinfo.c @@@ -1,5 -1,4 +1,5 @@@ #include "cache.h" +#include "config.h" #include "utf8.h" #include "strbuf.h" #include "mailinfo.h" @@@ -58,17 -57,17 +58,17 @@@ static void parse_bogus_from(struct mai static const char *unquote_comment(struct strbuf *outbuf, const char *in) { int c; - int take_next_litterally = 0; + int take_next_literally = 0; strbuf_addch(outbuf, '('); while ((c = *in++) != 0) { - if (take_next_litterally == 1) { - take_next_litterally = 0; + if (take_next_literally == 1) { + take_next_literally = 0; } else { switch (c) { case '\\': - take_next_litterally = 1; + take_next_literally = 1; continue; case '(': in = unquote_comment(outbuf, in); @@@ -88,15 -87,15 +88,15 @@@ static const char *unquote_quoted_string(struct strbuf *outbuf, const char *in) { int c; - int take_next_litterally = 0; + int take_next_literally = 0; while ((c = *in++) != 0) { - if (take_next_litterally == 1) { - take_next_litterally = 0; + if (take_next_literally == 1) { + take_next_literally = 0; } else { switch (c) { case '\\': - take_next_litterally = 1; + take_next_literally = 1; continue; case '"': return in; @@@ -149,14 -148,16 +149,14 @@@ static void handle_from(struct mailinf at = strchr(f.buf, '@'); if (!at) { parse_bogus_from(mi, from); - return; + goto out; } /* * If we already have one email, don't take any confusing lines */ - if (mi->email.len && strchr(at + 1, '@')) { - strbuf_release(&f); - return; - } + if (mi->email.len && strchr(at + 1, '@')) + goto out; /* Pick up the string around '@', possibly delimited with <> * pair; that is the email part. @@@ -196,7 -197,6 +196,7 @@@ } get_sane_name(&mi->name, &f, &mi->email); +out: strbuf_release(&f); } @@@ -367,16 -367,11 +367,16 @@@ static struct strbuf *decode_q_segment( while ((c = *in++) != 0) { if (c == '=') { - int d = *in++; + int ch, d = *in; if (d == '\n' || !d) break; /* drop trailing newline */ - strbuf_addch(out, (hexval(d) << 4) | hexval(*in++)); - continue; + ch = hex2chr(in); + if (ch >= 0) { + strbuf_addch(out, ch); + in += 2; + continue; + } + /* garbage -- fall through */ } if (rfc2047 && c == '_') /* rfc2047 4.2 (2) */ c = 0x20; @@@ -762,13 -757,8 +762,13 @@@ static int handle_commit_msg(struct mai assert(!mi->filter_stage); if (mi->header_stage) { - if (!line->len || (line->len == 1 && line->buf[0] == '\n')) + if (!line->len || (line->len == 1 && line->buf[0] == '\n')) { + if (mi->inbody_header_accum.len) { + flush_inbody_header_accum(mi); + mi->header_stage = 0; + } return 0; + } } if (mi->use_inbody_headers && mi->header_stage) { @@@ -827,7 -817,6 +827,7 @@@ static void handle_filter(struct mailin if (!handle_commit_msg(mi, line)) break; mi->filter_stage++; + /* fallthrough */ case 1: handle_patch(mi, line); break; @@@ -888,10 -877,7 +888,10 @@@ static int read_one_header_line(struct for (;;) { int peek; - peek = fgetc(in); ungetc(peek, in); + peek = fgetc(in); + if (peek == EOF) + break; + ungetc(peek, in); if (peek != ' ' && peek != '\t') break; if (strbuf_getline_lf(&continuation, in)) @@@ -925,7 -911,8 +925,7 @@@ again /* we hit an end boundary */ /* pop the current boundary off the stack */ strbuf_release(*(mi->content_top)); - free(*(mi->content_top)); - *(mi->content_top) = NULL; + FREE_AND_NULL(*(mi->content_top)); /* technically won't happen as is_multipart_boundary() will fail first. But just in case.. @@@ -934,7 -921,6 +934,7 @@@ error("Detected mismatched boundaries, can't recover"); mi->input_error = -1; mi->content_top = mi->content; + strbuf_release(&newline); return 0; } handle_filter(mi, &newline); @@@ -1108,10 -1094,6 +1108,10 @@@ int mailinfo(struct mailinfo *mi, cons do { peek = fgetc(mi->input); + if (peek == EOF) { + fclose(cmitmsg); + return error("empty patch: '%s'", patch); + } } while (isspace(peek)); ungetc(peek, mi->input); @@@ -1167,11 -1149,13 +1167,13 @@@ void clear_mailinfo(struct mailinfo *mi strbuf_release(&mi->inbody_header_accum); free(mi->message_id); - for (i = 0; mi->p_hdr_data[i]; i++) - strbuf_release(mi->p_hdr_data[i]); + if (mi->p_hdr_data) + for (i = 0; mi->p_hdr_data[i]; i++) + strbuf_release(mi->p_hdr_data[i]); free(mi->p_hdr_data); - for (i = 0; mi->s_hdr_data[i]; i++) - strbuf_release(mi->s_hdr_data[i]); + if (mi->s_hdr_data) + for (i = 0; mi->s_hdr_data[i]; i++) + strbuf_release(mi->s_hdr_data[i]); free(mi->s_hdr_data); while (mi->content < mi->content_top) {