summaryrefslogtreecommitdiff
path: root/mailinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'mailinfo.c')
-rw-r--r--mailinfo.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/mailinfo.c b/mailinfo.c
index e157ca6eb5..74d19aec0a 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -628,17 +628,71 @@ static int is_scissors_line(const struct strbuf *line)
gap * 2 < perforation);
}
+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 handle_commit_msg(struct mailinfo *mi, struct strbuf *line)
{
+ int is_empty_line;
+
assert(!mi->filter_stage);
- if (mi->header_stage) {
- if (!line->len || (line->len == 1 && line->buf[0] == '\n'))
+ is_empty_line = (!line->len || (line->len == 1 && line->buf[0] == '\n'));
+ if (mi->header_stage == 1) {
+ /*
+ * Haven't seen a known in-body header; discard an empty line.
+ */
+ if (is_empty_line)
return 0;
}
if (mi->use_inbody_headers && mi->header_stage) {
- mi->header_stage = check_header(mi, line, mi->s_hdr_data, 0);
+ int is_known_header = check_header(mi, line, mi->s_hdr_data, 0);
+
+ if (mi->header_stage == 2) {
+ /*
+ * an empty line after the in-body header block,
+ * or a line obviously not an attempt to invent
+ * an unsupported in-body header.
+ */
+ if (is_empty_line || !is_rfc2822_header(line))
+ mi->header_stage = 0;
+ if (is_empty_line)
+ return 0;
+ /* otherwise do not discard the line, but keep going */
+ } else if (is_known_header) {
+ /* We know we are in the in-body header block now. */
+ mi->header_stage = 2;
+ } else if (mi->header_stage != 2) {
+ /* garbage and we are not in the in-body header block */
+ mi->header_stage = 0;
+ }
+
if (mi->header_stage)
return 0;
} else
@@ -699,34 +753,6 @@ static void handle_filter(struct mailinfo *mi, struct strbuf *line)
}
}
-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;