diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-10-03 23:30:38 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-10-03 23:30:38 +0300 |
commit | fe252ef81a6ff96b3ed11e98feb96784d35f15f8 (patch) | |
tree | b21b23c04084ff1e8e42cfd8ffb97fc8e8187d35 /mailinfo.c | |
parent | e704c618dd513fb5dd14a8080da6e261895caefe (diff) | |
parent | f357e5de31595c28a303aaf5443c26f492441a6f (diff) |
Merge branch 'kd/mailinfo-quoted-string'
An author name, that spelled a backslash-quoted double quote in the
human readable part "My \"double quoted\" name", was not unquoted
correctly while applying a patch from a piece of e-mail.
* kd/mailinfo-quoted-string:
mailinfo: unescape quoted-pair in header fields
t5100-mailinfo: replace common path prefix with variable
Diffstat (limited to 'mailinfo.c')
-rw-r--r-- | mailinfo.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/mailinfo.c b/mailinfo.c index 2275b285f09..2fb3877ee44 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); |