#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "config.h"
#include "environment.h"
#include "gettext.h"
#include "hex-ll.h"
#include "utf8.h"
#include "strbuf.h"
#include "mailinfo.h"

static void cleanup_space(struct strbuf *sb)
{
	size_t pos, cnt;
	for (pos = 0; pos < sb->len; pos++) {
		if (isspace(sb->buf[pos])) {
			sb->buf[pos] = ' ';
			for (cnt = 0; isspace(sb->buf[pos + cnt + 1]); cnt++);
			strbuf_remove(sb, pos + 1, cnt);
		}
	}
}

static void get_sane_name(struct strbuf *out, struct strbuf *name, struct strbuf *email)
{
	struct strbuf *src = name;
	if (!name->len || 60 < name->len || strpbrk(name->buf, "@<>"))
		src = email;
	else if (name == out)
		return;
	strbuf_reset(out);
	strbuf_addbuf(out, src);
}

static void parse_bogus_from(struct mailinfo *mi, const struct strbuf *line)
{
	/* John Doe <johndoe> */

	char *bra, *ket;
	/* This is fallback, so do not bother if we already have an
	 * e-mail address.
	 */
	if (mi->email.len)
		return;

	bra = strchr(line->buf, '<');
	if (!bra)
		return;
	ket = strchr(bra, '>');
	if (!ket)
		return;

	strbuf_reset(&mi->email);
	strbuf_add(&mi->email, bra + 1, ket - bra - 1);

	strbuf_reset(&mi->name);
	strbuf_add(&mi->name, line->buf, bra - line->buf);
	strbuf_trim(&mi->name);
	get_sane_name(&mi->name, &mi->name, &mi->email);
}

static const char *unquote_comment(struct strbuf *outbuf, const char *in)
{
	int take_next_literally = 0;
	int depth = 1;

	strbuf_addch(outbuf, '(');

	while (*in) {
		int c = *in++;
		if (take_next_literally == 1) {
			take_next_literally = 0;
		} else {
			switch (c) {
			case '\\':
				take_next_literally = 1;
				continue;
			case '(':
				strbuf_addch(outbuf, '(');
				depth++;
				continue;
			case ')':
				strbuf_addch(outbuf, ')');
				if (!--depth)
					return in;
				continue;
			}
		}

		strbuf_addch(outbuf, c);
	}

	return in;
}

static const char *unquote_quoted_string(struct strbuf *outbuf, const char *in)
{
	int take_next_literally = 0;

	while (*in) {
		int c = *in++;
		if (take_next_literally == 1) {
			take_next_literally = 0;
		} else {
			switch (c) {
			case '\\':
				take_next_literally = 1;
				continue;
			case '"':
				return in;
			}
		}

		strbuf_addch(outbuf, c);
	}

	return in;
}

static void unquote_quoted_pair(struct strbuf *line)
{
	struct strbuf outbuf;
	const char *in = line->buf;
	int c;

	strbuf_init(&outbuf, line->len);

	while ((c = *in++) != 0) {
		switch (c) {
		case '"':
			in = unquote_quoted_string(&outbuf, in);
			continue;
		case '(':
			in = unquote_comment(&outbuf, in);
			continue;
		}

		strbuf_addch(&outbuf, c);
	}

	strbuf_swap(&outbuf, line);
	strbuf_release(&outbuf);

}

static void handle_from(struct mailinfo *mi, const struct strbuf *from)
{
	char *at;
	size_t el;
	struct strbuf f;

	strbuf_init(&f, from->len);
	strbuf_addbuf(&f, from);

	unquote_quoted_pair(&f);

	at = strchr(f.buf, '@');
	if (!at) {
		parse_bogus_from(mi, from);
		goto out;
	}

	/*
	 * If we already have one email, don't take any confusing lines
	 */
	if (mi->email.len && strchr(at + 1, '@'))
		goto out;

	/* Pick up the string around '@', possibly delimited with <>
	 * pair; that is the email part.
	 */
	while (at > f.buf) {
		char c = at[-1];
		if (isspace(c))
			break;
		if (c == '<') {
			at[-1] = ' ';
			break;
		}
		at--;
	}
	el = strcspn(at, " \n\t\r\v\f>");
	strbuf_reset(&mi->email);
	strbuf_add(&mi->email, at, el);
	strbuf_remove(&f, at - f.buf, el + (at[el] ? 1 : 0));

	/* The remainder is name.  It could be
	 *
	 * - "John Doe <john.doe@xz>"			(a), or
	 * - "john.doe@xz (John Doe)"			(b), or
	 * - "John (zzz) Doe <john.doe@xz> (Comment)"	(c)
	 *
	 * but we have removed the email part, so
	 *
	 * - remove extra spaces which could stay after email (case 'c'), and
	 * - trim from both ends, possibly removing the () pair at the end
	 *   (cases 'a' and 'b').
	 */
	cleanup_space(&f);
	strbuf_trim(&f);
	if (f.buf[0] == '(' && f.len && f.buf[f.len - 1] == ')') {
		strbuf_remove(&f, 0, 1);
		strbuf_setlen(&f, f.len - 1);
	}

	get_sane_name(&mi->name, &f, &mi->email);
out:
	strbuf_release(&f);
}

static void handle_header(struct strbuf **out, const struct strbuf *line)
{
	if (!*out) {
		*out = xmalloc(sizeof(struct strbuf));
		strbuf_init(*out, line->len);
	} else
		strbuf_reset(*out);

	strbuf_addbuf(*out, line);
}

/* NOTE NOTE NOTE.  We do not claim we do full MIME.  We just attempt
 * to have enough heuristics to grok MIME encoded patches often found
 * on our mailing lists.  For example, we do not even treat header lines
 * case insensitively.
 */

static int slurp_attr(const char *line, const char *name, struct strbuf *attr)
{
	const char *ends, *ap = strcasestr(line, name);
	size_t sz;

	strbuf_setlen(attr, 0);
	if (!ap)
		return 0;
	ap += strlen(name);
	if (*ap == '"') {
		ap++;
		ends = "\"";
	}
	else
		ends = "; \t";
	sz = strcspn(ap, ends);
	strbuf_add(attr, ap, sz);
	return 1;
}

static int has_attr_value(const char *line, const char *name, const char *value)
{
	struct strbuf sb = STRBUF_INIT;
	int rc = slurp_attr(line, name, &sb) && !strcasecmp(sb.buf, value);
	strbuf_release(&sb);
	return rc;
}

static void handle_content_type(struct mailinfo *mi, struct strbuf *line)
{
	struct strbuf *boundary = xmalloc(sizeof(struct strbuf));
	strbuf_init(boundary, line->len);

	mi->format_flowed = has_attr_value(line->buf, "format=", "flowed");
	mi->delsp = has_attr_value(line->buf, "delsp=", "yes");

	if (slurp_attr(line->buf, "boundary=", boundary)) {
		strbuf_insertstr(boundary, 0, "--");
		if (++mi->content_top >= &mi->content[MAX_BOUNDARIES]) {
			error("Too many boundaries to handle");
			mi->input_error = -1;
			mi->content_top = &mi->content[MAX_BOUNDARIES] - 1;
			strbuf_release(boundary);
			free(boundary);
			return;
		}
		*(mi->content_top) = boundary;
		boundary = NULL;
	}
	slurp_attr(line->buf, "charset=", &mi->charset);

	if (boundary) {
		strbuf_release(boundary);
		free(boundary);
	}
}

static void handle_content_transfer_encoding(struct mailinfo *mi,
					     const struct strbuf *line)
{
	if (strcasestr(line->buf, "base64"))
		mi->transfer_encoding = TE_BASE64;
	else if (strcasestr(line->buf, "quoted-printable"))
		mi->transfer_encoding = TE_QP;
	else
		mi->transfer_encoding = TE_DONTCARE;
}

static int is_multipart_boundary(struct mailinfo *mi, const struct strbuf *line)
{
	struct strbuf *content_top = *(mi->content_top);

	return ((content_top->len <= line->len) &&
		!memcmp(line->buf, content_top->buf, content_top->len));
}

static void cleanup_subject(struct mailinfo *mi, struct strbuf *subject)
{
	size_t at = 0;

	while (at < subject->len) {
		char *pos;
		size_t remove;

		switch (subject->buf[at]) {
		case 'r': case 'R':
			if (subject->len <= at + 3)
				break;
			if ((subject->buf[at + 1] == 'e' ||
			     subject->buf[at + 1] == 'E') &&
			    subject->buf[at + 2] == ':') {
				strbuf_remove(subject, at, 3);
				continue;
			}
			at++;
			break;
		case ' ': case '\t': case ':':
			strbuf_remove(subject, at, 1);
			continue;
		case '[':
			pos = strchr(subject->buf + at, ']');
			if (!pos)
				break;
			remove = pos - (subject->buf + at) + 1;
			if (!mi->keep_non_patch_brackets_in_subject ||
			    (7 <= remove &&
			     memmem(subject->buf + at, remove, "PATCH", 5)))
				strbuf_remove(subject, at, remove);
			else {
				at += remove;
				/*
				 * If the input had a space after the ], keep
				 * it.  We don't bother with finding the end of
				 * the space, since we later normalize it
				 * anyway.
				 */
				if (isspace(subject->buf[at]))
					at += 1;
			}
			continue;
		}
		break;
	}
	strbuf_trim(subject);
}

static const char * const header[] = {
	"From", "Subject", "Date",
};

static inline int skip_header(const struct strbuf *line, const char *hdr,
			      const char **outval)
{
	const char *val;
	if (!skip_iprefix(line->buf, hdr, &val) ||
	    *val++ != ':')
		return 0;
	while (isspace(*val))
		val++;
	*outval = val;
	return 1;
}

static int is_format_patch_separator(const char *line, int len)
{
	static const char SAMPLE[] =
		"From e6807f3efca28b30decfecb1732a56c7db1137ee Mon Sep 17 00:00:00 2001\n";
	const char *cp;

	if (len != strlen(SAMPLE))
		return 0;
	if (!skip_prefix(line, "From ", &cp))
		return 0;
	if (strspn(cp, "0123456789abcdef") != 40)
		return 0;
	cp += 40;
	return !memcmp(SAMPLE + (cp - line), cp, strlen(SAMPLE) - (cp - line));
}

static int decode_q_segment(struct strbuf *out, const struct strbuf *q_seg,
			    int rfc2047)
{
	const char *in = q_seg->buf;
	int c;
	strbuf_grow(out, q_seg->len);

	while ((c = *in++) != 0) {
		if (c == '=') {
			int ch, d = *in;
			if (d == '\n' || !d)
				break; /* drop trailing newline */
			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;
		strbuf_addch(out, c);
	}
	return 0;
}

static int decode_b_segment(struct strbuf *out, const struct strbuf *b_seg)
{
	/* Decode in..ep, possibly in-place to ot */
	int c, pos = 0, acc = 0;
	const char *in = b_seg->buf;
	strbuf_grow(out, b_seg->len);

	while ((c = *in++) != 0) {
		if (c == '+')
			c = 62;
		else if (c == '/')
			c = 63;
		else if ('A' <= c && c <= 'Z')
			c -= 'A';
		else if ('a' <= c && c <= 'z')
			c -= 'a' - 26;
		else if ('0' <= c && c <= '9')
			c -= '0' - 52;
		else
			continue; /* garbage */
		switch (pos++) {
		case 0:
			acc = (c << 2);
			break;
		case 1:
			strbuf_addch(out, (acc | (c >> 4)));
			acc = (c & 15) << 4;
			break;
		case 2:
			strbuf_addch(out, (acc | (c >> 2)));
			acc = (c & 3) << 6;
			break;
		case 3:
			strbuf_addch(out, (acc | c));
			acc = pos = 0;
			break;
		}
	}
	return 0;
}

static int convert_to_utf8(struct mailinfo *mi,
			   struct strbuf *line, const char *charset)
{
	char *out;
	size_t out_len;

	if (!mi->metainfo_charset || !charset || !*charset)
		return 0;

	if (same_encoding(mi->metainfo_charset, charset))
		return 0;
	out = reencode_string_len(line->buf, line->len,
				  mi->metainfo_charset, charset, &out_len);
	if (!out) {
		mi->input_error = -1;
		return error("cannot convert from %s to %s",
			     charset, mi->metainfo_charset);
	}
	strbuf_attach(line, out, out_len, out_len + 1);
	return 0;
}

static void decode_header(struct mailinfo *mi, struct strbuf *it)
{
	char *in, *ep, *cp;
	struct strbuf outbuf = STRBUF_INIT, dec = STRBUF_INIT;
	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) {
		int encoding;
		strbuf_reset(&charset_q);
		strbuf_reset(&piecebuf);

		if (in != ep) {
			/*
			 * We are about to process an encoded-word
			 * that begins at ep, but there is something
			 * before the encoded word.
			 */
			char *scan;
			for (scan = in; scan < ep; scan++)
				if (!isspace(*scan))
					break;

			if (scan != ep || in == it->buf) {
				/*
				 * We should not lose that "something",
				 * unless we have just processed an
				 * encoded-word, and there is only LWS
				 * before the one we are about to process.
				 */
				strbuf_add(&outbuf, in, ep - in);
			}
		}
		/* E.g.
		 * ep : "=?iso-2022-jp?B?GyR...?= foo"
		 * ep : "=?ISO-8859-1?Q?Foo=FCbar?= baz"
		 */
		ep += 2;

		if (ep - it->buf >= it->len || !(cp = strchr(ep, '?')))
			goto release_return;

		if (cp + 3 - it->buf > it->len)
			goto release_return;
		strbuf_add(&charset_q, ep, cp - ep);

		encoding = cp[1];
		if (!encoding || cp[2] != '?')
			goto release_return;
		ep = strstr(cp + 3, "?=");
		if (!ep)
			goto release_return;
		strbuf_add(&piecebuf, cp + 3, ep - cp - 3);
		switch (tolower(encoding)) {
		default:
			goto release_return;
		case 'b':
			if ((found_error = decode_b_segment(&dec, &piecebuf)))
				goto release_return;
			break;
		case 'q':
			if ((found_error = decode_q_segment(&dec, &piecebuf, 1)))
				goto release_return;
			break;
		}
		if (convert_to_utf8(mi, &dec, charset_q.buf))
			goto release_return;

		strbuf_addbuf(&outbuf, &dec);
		strbuf_release(&dec);
		in = ep + 2;
	}
	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);
	strbuf_release(&dec);

	if (found_error)
		mi->input_error = -1;
}

/*
 * Returns true if "line" contains a header matching "hdr", in which case "val"
 * will contain the value of the header with any RFC2047 B and Q encoding
 * unwrapped, and optionally normalize the meta information to utf8.
 */
static int parse_header(const struct strbuf *line,
			const char *hdr,
			struct mailinfo *mi,
			struct strbuf *val)
{
	const char *val_str;

	if (!skip_header(line, hdr, &val_str))
		return 0;
	strbuf_addstr(val, val_str);
	decode_header(mi, val);
	return 1;
}

static int check_header(struct mailinfo *mi,
			const struct strbuf *line,
			struct strbuf *hdr_data[], int overwrite)
{
	int i, ret = 0;
	struct strbuf sb = STRBUF_INIT;

	/* search for the interesting parts */
	for (i = 0; i < ARRAY_SIZE(header); i++) {
		if ((!hdr_data[i] || overwrite) &&
		    parse_header(line, header[i], mi, &sb)) {
			handle_header(&hdr_data[i], &sb);
			ret = 1;
			goto check_header_out;
		}
	}

	/* Content stuff */
	if (parse_header(line, "Content-Type", mi, &sb)) {
		handle_content_type(mi, &sb);
		ret = 1;
		goto check_header_out;
	}
	if (parse_header(line, "Content-Transfer-Encoding", mi, &sb)) {
		handle_content_transfer_encoding(mi, &sb);
		ret = 1;
		goto check_header_out;
	}
	if (parse_header(line, "Message-ID", mi, &sb)) {
		if (mi->add_message_id)
			mi->message_id = strbuf_detach(&sb, NULL);
		ret = 1;
		goto check_header_out;
	}

check_header_out:
	strbuf_release(&sb);
	return ret;
}

/*
 * Returns 1 if the given line or any line beginning with the given line is an
 * in-body header (that is, check_header will succeed when passed
 * mi->s_hdr_data).
 */
static int is_inbody_header(const struct mailinfo *mi,
			    const struct strbuf *line)
{
	int i;
	const char *val;
	for (i = 0; i < ARRAY_SIZE(header); i++)
		if (!mi->s_hdr_data[i] && skip_header(line, header[i], &val))
			return 1;
	return 0;
}

static void decode_transfer_encoding(struct mailinfo *mi, struct strbuf *line)
{
	struct strbuf ret = STRBUF_INIT;

	switch (mi->transfer_encoding) {
	case TE_QP:
		decode_q_segment(&ret, line, 0);
		break;
	case TE_BASE64:
		decode_b_segment(&ret, line);
		break;
	case TE_DONTCARE:
	default:
		return;
	}
	strbuf_reset(line);
	strbuf_addbuf(line, &ret);
	strbuf_release(&ret);
}

static inline int patchbreak(const struct strbuf *line)
{
	size_t i;

	/* Beginning of a "diff -" header? */
	if (starts_with(line->buf, "diff -"))
		return 1;

	/* CVS "Index: " line? */
	if (starts_with(line->buf, "Index: "))
		return 1;

	/*
	 * "--- <filename>" starts patches without headers
	 * "---<sp>*" is a manual separator
	 */
	if (line->len < 4)
		return 0;

	if (starts_with(line->buf, "---")) {
		/* space followed by a filename? */
		if (line->buf[3] == ' ' && !isspace(line->buf[4]))
			return 1;
		/* Just whitespace? */
		for (i = 3; i < line->len; i++) {
			unsigned char c = line->buf[i];
			if (c == '\n')
				return 1;
			if (!isspace(c))
				break;
		}
		return 0;
	}
	return 0;
}

static int is_scissors_line(const char *line)
{
	const char *c;
	int scissors = 0, gap = 0;
	const char *first_nonblank = NULL, *last_nonblank = NULL;
	int visible, perforation = 0, in_perforation = 0;

	for (c = line; *c; c++) {
		if (isspace(*c)) {
			if (in_perforation) {
				perforation++;
				gap++;
			}
			continue;
		}
		last_nonblank = c;
		if (!first_nonblank)
			first_nonblank = c;
		if (*c == '-') {
			in_perforation = 1;
			perforation++;
			continue;
		}
		if (starts_with(c, ">8") || starts_with(c, "8<") ||
		    starts_with(c, ">%") || starts_with(c, "%<")) {
			in_perforation = 1;
			perforation += 2;
			scissors += 2;
			c++;
			continue;
		}
		in_perforation = 0;
	}

	/*
	 * The mark must be at least 8 bytes long (e.g. "-- >8 --").
	 * Even though there can be arbitrary cruft on the same line
	 * (e.g. "cut here"), in order to avoid misidentification, the
	 * perforation must occupy more than a third of the visible
	 * width of the line, and dashes and scissors must occupy more
	 * than half of the perforation.
	 */

	if (first_nonblank && last_nonblank)
		visible = last_nonblank - first_nonblank + 1;
	else
		visible = 0;
	return (scissors && 8 <= visible &&
		visible < perforation * 3 &&
		gap * 2 < perforation);
}

static void flush_inbody_header_accum(struct mailinfo *mi)
{
	if (!mi->inbody_header_accum.len)
		return;
	if (!check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data, 0))
		BUG("inbody_header_accum, if not empty, must always contain a valid in-body header");
	strbuf_reset(&mi->inbody_header_accum);
}

static int check_inbody_header(struct mailinfo *mi, const struct strbuf *line)
{
	if (mi->inbody_header_accum.len &&
	    (line->buf[0] == ' ' || line->buf[0] == '\t')) {
		if (mi->use_scissors && is_scissors_line(line->buf)) {
			/*
			 * This is a scissors line; do not consider this line
			 * as a header continuation line.
			 */
			flush_inbody_header_accum(mi);
			return 0;
		}
		strbuf_strip_suffix(&mi->inbody_header_accum, "\n");
		strbuf_addbuf(&mi->inbody_header_accum, line);
		return 1;
	}

	flush_inbody_header_accum(mi);

	if (starts_with(line->buf, ">From") && isspace(line->buf[5]))
		return is_format_patch_separator(line->buf + 1, line->len - 1);
	if (starts_with(line->buf, "[PATCH]") && isspace(line->buf[7])) {
		int i;
		for (i = 0; i < ARRAY_SIZE(header); i++)
			if (!strcmp("Subject", header[i])) {
				handle_header(&mi->s_hdr_data[i], line);
				return 1;
			}
		return 0;
	}
	if (is_inbody_header(mi, line)) {
		strbuf_addbuf(&mi->inbody_header_accum, line);
		return 1;
	}
	return 0;
}

static int handle_commit_msg(struct mailinfo *mi, struct strbuf *line)
{
	assert(!mi->filter_stage);

	if (mi->header_stage) {
		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) {
		mi->header_stage = check_inbody_header(mi, line);
		if (mi->header_stage)
			return 0;
	} else
		/* Only trim the first (blank) line of the commit message
		 * when ignoring in-body headers.
		 */
		mi->header_stage = 0;

	/* normalize the log message to UTF-8. */
	if (convert_to_utf8(mi, line, mi->charset.buf))
		return 0; /* mi->input_error already set */

	if (mi->use_scissors && is_scissors_line(line->buf)) {
		int i;

		strbuf_setlen(&mi->log_message, 0);
		mi->header_stage = 1;

		/*
		 * We may have already read "secondary headers"; purge
		 * them to give ourselves a clean restart.
		 */
		for (i = 0; i < ARRAY_SIZE(header); i++) {
			if (mi->s_hdr_data[i])
				strbuf_release(mi->s_hdr_data[i]);
			FREE_AND_NULL(mi->s_hdr_data[i]);
		}
		return 0;
	}

	if (patchbreak(line)) {
		if (mi->message_id)
			strbuf_addf(&mi->log_message,
				    "Message-ID: %s\n", mi->message_id);
		return 1;
	}

	strbuf_addbuf(&mi->log_message, line);
	return 0;
}

static void handle_patch(struct mailinfo *mi, const struct strbuf *line)
{
	fwrite(line->buf, 1, line->len, mi->patchfile);
	mi->patch_lines++;
}

static void handle_filter(struct mailinfo *mi, struct strbuf *line)
{
	switch (mi->filter_stage) {
	case 0:
		if (!handle_commit_msg(mi, line))
			break;
		mi->filter_stage++;
		/* fallthrough */
	case 1:
		handle_patch(mi, line);
		break;
	}
}

static int is_rfc2822_header(const struct strbuf *line)
{
	/*
	 * The section that defines the loosest possible
	 * field name is "3.6.8 Optional fields".
	 *
	 * optional-field = field-name ":" unstructured CRLF
	 * field-name = 1*ftext
	 * ftext = %d33-57 / %59-126
	 */
	int ch;
	char *cp = line->buf;

	/* Count mbox From headers as headers */
	if (starts_with(cp, "From ") || starts_with(cp, ">From "))
		return 1;

	while ((ch = *cp++)) {
		if (ch == ':')
			return 1;
		if ((33 <= ch && ch <= 57) ||
		    (59 <= ch && ch <= 126))
			continue;
		break;
	}
	return 0;
}

static int read_one_header_line(struct strbuf *line, FILE *in)
{
	struct strbuf continuation = STRBUF_INIT;

	/* Get the first part of the line. */
	if (strbuf_getline_lf(line, in))
		return 0;

	/*
	 * Is it an empty line or not a valid rfc2822 header?
	 * If so, stop here, and return false ("not a header")
	 */
	strbuf_rtrim(line);
	if (!line->len || !is_rfc2822_header(line)) {
		/* Re-add the newline */
		strbuf_addch(line, '\n');
		return 0;
	}

	/*
	 * Now we need to eat all the continuation lines..
	 * Yuck, 2822 header "folding"
	 */
	for (;;) {
		int peek;

		peek = fgetc(in);
		if (peek == EOF)
			break;
		ungetc(peek, in);
		if (peek != ' ' && peek != '\t')
			break;
		if (strbuf_getline_lf(&continuation, in))
			break;
		continuation.buf[0] = ' ';
		strbuf_rtrim(&continuation);
		strbuf_addbuf(line, &continuation);
	}
	strbuf_release(&continuation);

	return 1;
}

static int find_boundary(struct mailinfo *mi, struct strbuf *line)
{
	while (!strbuf_getline_lf(line, mi->input)) {
		if (*(mi->content_top) && is_multipart_boundary(mi, line))
			return 1;
	}
	return 0;
}

static int handle_boundary(struct mailinfo *mi, struct strbuf *line)
{
	struct strbuf newline = STRBUF_INIT;

	strbuf_addch(&newline, '\n');
again:
	if (line->len >= (*(mi->content_top))->len + 2 &&
	    !memcmp(line->buf + (*(mi->content_top))->len, "--", 2)) {
		/* we hit an end boundary */
		/* pop the current boundary off the stack */
		strbuf_release(*(mi->content_top));
		FREE_AND_NULL(*(mi->content_top));

		/* technically won't happen as is_multipart_boundary()
		   will fail first.  But just in case..
		 */
		if (--mi->content_top < mi->content) {
			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);
		strbuf_release(&newline);
		if (mi->input_error)
			return 0;

		/* skip to the next boundary */
		if (!find_boundary(mi, line))
			return 0;
		goto again;
	}

	/* set some defaults */
	mi->transfer_encoding = TE_DONTCARE;
	strbuf_reset(&mi->charset);

	/* slurp in this section's info */
	while (read_one_header_line(line, mi->input))
		check_header(mi, line, mi->p_hdr_data, 0);

	strbuf_release(&newline);
	/* replenish line */
	if (strbuf_getline_lf(line, mi->input))
		return 0;
	strbuf_addch(line, '\n');
	return 1;
}

static void handle_filter_flowed(struct mailinfo *mi, struct strbuf *line,
				 struct strbuf *prev)
{
	size_t len = line->len;
	const char *rest;

	if (!mi->format_flowed) {
		if (len >= 2 &&
		    line->buf[len - 2] == '\r' &&
		    line->buf[len - 1] == '\n') {
			mi->have_quoted_cr = 1;
			if (mi->quoted_cr == quoted_cr_strip) {
				strbuf_setlen(line, len - 2);
				strbuf_addch(line, '\n');
				len--;
			}
		}
		handle_filter(mi, line);
		return;
	}

	if (line->buf[len - 1] == '\n') {
		len--;
		if (len && line->buf[len - 1] == '\r')
			len--;
	}

	/* Keep signature separator as-is. */
	if (skip_prefix(line->buf, "-- ", &rest) && rest - line->buf == len) {
		if (prev->len) {
			handle_filter(mi, prev);
			strbuf_reset(prev);
		}
		handle_filter(mi, line);
		return;
	}

	/* Unstuff space-stuffed line. */
	if (len && line->buf[0] == ' ') {
		strbuf_remove(line, 0, 1);
		len--;
	}

	/* Save flowed line for later, but without the soft line break. */
	if (len && line->buf[len - 1] == ' ') {
		strbuf_add(prev, line->buf, len - !!mi->delsp);
		return;
	}

	/* Prepend any previous partial lines */
	strbuf_insert(line, 0, prev->buf, prev->len);
	strbuf_reset(prev);

	handle_filter(mi, line);
}

static void summarize_quoted_cr(struct mailinfo *mi)
{
	if (mi->have_quoted_cr &&
	    mi->quoted_cr == quoted_cr_warn)
		warning(_("quoted CRLF detected"));
}

static void handle_body(struct mailinfo *mi, struct strbuf *line)
{
	struct strbuf prev = STRBUF_INIT;

	/* Skip up to the first boundary */
	if (*(mi->content_top)) {
		if (!find_boundary(mi, line))
			goto handle_body_out;
	}

	do {
		/* process any boundary lines */
		if (*(mi->content_top) && is_multipart_boundary(mi, line)) {
			/* flush any leftover */
			if (prev.len) {
				handle_filter(mi, &prev);
				strbuf_reset(&prev);
			}
			summarize_quoted_cr(mi);
			mi->have_quoted_cr = 0;
			if (!handle_boundary(mi, line))
				goto handle_body_out;
		}

		/* Unwrap transfer encoding */
		decode_transfer_encoding(mi, line);

		switch (mi->transfer_encoding) {
		case TE_BASE64:
		case TE_QP:
		{
			struct strbuf **lines, **it, *sb;

			/* Prepend any previous partial lines */
			strbuf_insert(line, 0, prev.buf, prev.len);
			strbuf_reset(&prev);

			/*
			 * This is a decoded line that may contain
			 * multiple new lines.  Pass only one chunk
			 * at a time to handle_filter()
			 */
			lines = strbuf_split(line, '\n');
			for (it = lines; (sb = *it); it++) {
				if (!*(it + 1)) /* The last line */
					if (sb->buf[sb->len - 1] != '\n') {
						/* Partial line, save it for later. */
						strbuf_addbuf(&prev, sb);
						break;
					}
				handle_filter_flowed(mi, sb, &prev);
			}
			/*
			 * The partial chunk is saved in "prev" and will be
			 * appended by the next iteration of read_line_with_nul().
			 */
			strbuf_list_free(lines);
			break;
		}
		default:
			handle_filter_flowed(mi, line, &prev);
		}

		if (mi->input_error)
			break;
	} while (!strbuf_getwholeline(line, mi->input, '\n'));

	if (prev.len)
		handle_filter(mi, &prev);
	summarize_quoted_cr(mi);

	flush_inbody_header_accum(mi);

handle_body_out:
	strbuf_release(&prev);
}

static void output_header_lines(FILE *fout, const char *hdr, const struct strbuf *data)
{
	const char *sp = data->buf;
	while (1) {
		const char *ep = strchr(sp, '\n');
		int len;
		if (!ep)
			len = strlen(sp);
		else
			len = ep - sp;
		fprintf(fout, "%s: %.*s\n", hdr, len, sp);
		if (!ep)
			break;
		sp = ep + 1;
	}
}

static void handle_info(struct mailinfo *mi)
{
	struct strbuf *hdr;
	int i;

	for (i = 0; i < ARRAY_SIZE(header); i++) {
		/* only print inbody headers if we output a patch file */
		if (mi->patch_lines && mi->s_hdr_data[i])
			hdr = mi->s_hdr_data[i];
		else if (mi->p_hdr_data[i])
			hdr = mi->p_hdr_data[i];
		else
			continue;

		if (memchr(hdr->buf, '\0', hdr->len)) {
			error("a NUL byte in '%s' is not allowed.", header[i]);
			mi->input_error = -1;
		}

		if (!strcmp(header[i], "Subject")) {
			if (!mi->keep_subject) {
				cleanup_subject(mi, hdr);
				cleanup_space(hdr);
			}
			output_header_lines(mi->output, "Subject", hdr);
		} else if (!strcmp(header[i], "From")) {
			cleanup_space(hdr);
			handle_from(mi, hdr);
			fprintf(mi->output, "Author: %s\n", mi->name.buf);
			fprintf(mi->output, "Email: %s\n", mi->email.buf);
		} else {
			cleanup_space(hdr);
			fprintf(mi->output, "%s: %s\n", header[i], hdr->buf);
		}
	}
	fprintf(mi->output, "\n");
}

int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)
{
	FILE *cmitmsg;
	int peek;
	struct strbuf line = STRBUF_INIT;

	cmitmsg = fopen(msg, "w");
	if (!cmitmsg) {
		perror(msg);
		return -1;
	}
	mi->patchfile = fopen(patch, "w");
	if (!mi->patchfile) {
		perror(patch);
		fclose(cmitmsg);
		return -1;
	}

	mi->p_hdr_data = xcalloc(ARRAY_SIZE(header), sizeof(*(mi->p_hdr_data)));
	mi->s_hdr_data = xcalloc(ARRAY_SIZE(header), sizeof(*(mi->s_hdr_data)));

	do {
		peek = fgetc(mi->input);
		if (peek == EOF) {
			fclose(cmitmsg);
			return error("empty patch: '%s'", patch);
		}
	} while (isspace(peek));
	ungetc(peek, mi->input);

	/* process the email header */
	while (read_one_header_line(&line, mi->input))
		check_header(mi, &line, mi->p_hdr_data, 1);

	handle_body(mi, &line);
	fwrite(mi->log_message.buf, 1, mi->log_message.len, cmitmsg);
	fclose(cmitmsg);
	fclose(mi->patchfile);

	handle_info(mi);
	strbuf_release(&line);
	return mi->input_error;
}

int mailinfo_parse_quoted_cr_action(const char *actionstr, int *action)
{
	if (!strcmp(actionstr, "nowarn"))
		*action = quoted_cr_nowarn;
	else if (!strcmp(actionstr, "warn"))
		*action = quoted_cr_warn;
	else if (!strcmp(actionstr, "strip"))
		*action = quoted_cr_strip;
	else
		return -1;
	return 0;
}

static int git_mailinfo_config(const char *var, const char *value,
			       const struct config_context *ctx, void *mi_)
{
	struct mailinfo *mi = mi_;

	if (!starts_with(var, "mailinfo."))
		return git_default_config(var, value, ctx, NULL);
	if (!strcmp(var, "mailinfo.scissors")) {
		mi->use_scissors = git_config_bool(var, value);
		return 0;
	}
	if (!strcmp(var, "mailinfo.quotedcr")) {
		if (!value)
			return config_error_nonbool(var);
		if (mailinfo_parse_quoted_cr_action(value, &mi->quoted_cr) != 0)
			return error(_("bad action '%s' for '%s'"), value, var);
		return 0;
	}
	/* perhaps others here */
	return 0;
}

void setup_mailinfo(struct repository *r, struct mailinfo *mi)
{
	memset(mi, 0, sizeof(*mi));
	strbuf_init(&mi->name, 0);
	strbuf_init(&mi->email, 0);
	strbuf_init(&mi->charset, 0);
	strbuf_init(&mi->log_message, 0);
	strbuf_init(&mi->inbody_header_accum, 0);
	mi->quoted_cr = quoted_cr_warn;
	mi->header_stage = 1;
	mi->use_inbody_headers = 1;
	mi->content_top = mi->content;
	repo_config(r, git_mailinfo_config, mi);
}

void clear_mailinfo(struct mailinfo *mi)
{
	strbuf_release(&mi->name);
	strbuf_release(&mi->email);
	strbuf_release(&mi->charset);
	strbuf_release(&mi->inbody_header_accum);
	free(mi->message_id);

	for (size_t i = 0; i < ARRAY_SIZE(header); i++) {
		if (!mi->p_hdr_data[i])
			continue;
		strbuf_release(mi->p_hdr_data[i]);
		free(mi->p_hdr_data[i]);
	}
	free(mi->p_hdr_data);

	for (size_t i = 0; i < ARRAY_SIZE(header); i++) {
		if (!mi->s_hdr_data[i])
			continue;
		strbuf_release(mi->s_hdr_data[i]);
		free(mi->s_hdr_data[i]);
	}
	free(mi->s_hdr_data);

	while (mi->content < mi->content_top) {
		free(*(mi->content_top));
		mi->content_top--;
	}

	strbuf_release(&mi->log_message);
}
