You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.3 KiB
129 lines
3.3 KiB
From: A <author@example.com> |
|
Subject: [PATCH] mailinfo: support format=flowed |
|
Message-ID: <aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa@example.com> |
|
Date: Sat, 25 Aug 2018 22:04:50 +0200 |
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 |
|
Thunderbird/60.0 |
|
MIME-Version: 1.0 |
|
Content-Type: text/plain; charset=utf-8; format=flowed |
|
Content-Language: en-US |
|
Content-Transfer-Encoding: 7bit |
|
|
|
--- |
|
mailinfo.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
|
1 file changed, 62 insertions(+), 2 deletions(-) |
|
|
|
diff --git a/mailinfo.c b/mailinfo.c |
|
index 3281a37d51..b395adbdf2 100644 |
|
--- a/mailinfo.c |
|
+++ b/mailinfo.c |
|
@@ -237,11 +237,22 @@ static int slurp_attr(const char *line, const char |
|
*name, struct strbuf *attr) |
|
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_insert(boundary, 0, "--", 2); |
|
if (++mi->content_top >= &mi->content[MAX_BOUNDARIES]) { |
|
@@ -964,6 +975,52 @@ static int handle_boundary(struct mailinfo *mi, |
|
struct strbuf *line) |
|
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) { |
|
+ 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 handle_body(struct mailinfo *mi, struct strbuf *line) |
|
{ |
|
struct strbuf prev = STRBUF_INIT; |
|
@@ -1012,7 +1069,7 @@ static void handle_body(struct mailinfo *mi, |
|
struct strbuf *line) |
|
strbuf_addbuf(&prev, sb); |
|
break; |
|
} |
|
- handle_filter(mi, sb); |
|
+ handle_filter_flowed(mi, sb, &prev); |
|
} |
|
/* |
|
* The partial chunk is saved in "prev" and will be |
|
@@ -1022,13 +1079,16 @@ static void handle_body(struct mailinfo *mi, |
|
struct strbuf *line) |
|
break; |
|
} |
|
default: |
|
- handle_filter(mi, line); |
|
+ 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); |
|
+ |
|
flush_inbody_header_accum(mi); |
|
|
|
handle_body_out: |
|
-- |
|
2.18.0
|
|
|