diff options
Diffstat (limited to 'mailinfo.c')
-rw-r--r-- | mailinfo.c | 91 |
1 files changed, 84 insertions, 7 deletions
diff --git a/mailinfo.c b/mailinfo.c index 9f19ca1080..b4118a0275 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -54,6 +54,86 @@ static void parse_bogus_from(struct mailinfo *mi, const struct strbuf *line) get_sane_name(&mi->name, &mi->name, &mi->email); } +static const char *unquote_comment(struct strbuf *outbuf, const char *in) +{ + int c; + int take_next_litterally = 0; + + strbuf_addch(outbuf, '('); + + while ((c = *in++) != 0) { + if (take_next_litterally == 1) { + take_next_litterally = 0; + } else { + switch (c) { + case '\\': + take_next_litterally = 1; + continue; + case '(': + in = unquote_comment(outbuf, in); + continue; + case ')': + strbuf_addch(outbuf, ')'); + return in; + } + } + + strbuf_addch(outbuf, c); + } + + return in; +} + +static const char *unquote_quoted_string(struct strbuf *outbuf, const char *in) +{ + int c; + int take_next_litterally = 0; + + while ((c = *in++) != 0) { + if (take_next_litterally == 1) { + take_next_litterally = 0; + } else { + switch (c) { + case '\\': + take_next_litterally = 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; @@ -63,6 +143,8 @@ static void handle_from(struct mailinfo *mi, const struct strbuf *from) strbuf_init(&f, from->len); strbuf_addbuf(&f, from); + unquote_quoted_pair(&f); + at = strchr(f.buf, '@'); if (!at) { parse_bogus_from(mi, from); @@ -179,12 +261,6 @@ static void handle_content_type(struct mailinfo *mi, struct strbuf *line) } } -static void handle_message_id(struct mailinfo *mi, const struct strbuf *line) -{ - if (mi->add_message_id) - mi->message_id = strdup(line->buf); -} - static void handle_content_transfer_encoding(struct mailinfo *mi, const struct strbuf *line) { @@ -495,7 +571,8 @@ static int check_header(struct mailinfo *mi, len = strlen("Message-Id: "); strbuf_add(&sb, line->buf + len, line->len - len); decode_header(mi, &sb); - handle_message_id(mi, &sb); + if (mi->add_message_id) + mi->message_id = strbuf_detach(&sb, NULL); ret = 1; goto check_header_out; } |