diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-10-11 14:20:31 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-10-11 14:20:32 -0700 |
commit | e1eb84cccb927834acae58ec2c0f727c7bf184c7 (patch) | |
tree | 59431a150dcd01bfe822c939311a6a4d6560a72a /mailinfo.c | |
parent | Merge branch 'pb/rev-list-reverse-with-count' into maint (diff) | |
parent | mailinfo: unescape quoted-pair in header fields (diff) | |
download | tgif-e1eb84cccb927834acae58ec2c0f727c7bf184c7.tar.xz |
Merge branch 'kd/mailinfo-quoted-string' into maint
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 e19abe3cb9..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); |