(Sorry I didn't chime in on this tangent. My life has been very busy since Google finished acquiring ITA Software. At least it's a good kind of busy. :) ) I'd be happy to see something like this get in. I've often noticed git-send-email telling me that it couldn't parse an address out of my signed-of-by lines, but I never stopped and took the time to look into it. -Alejandro On 04/08/2011 06:40 PM, Jeff King wrote: > On Fri, Apr 08, 2011 at 03:25:09PM -0700, Junio C Hamano wrote: > >> Jeff King <peff@xxxxxxxx> writes: >> >>> I disagree. Format-patch claims to make an mbox, so it should make one >>> that is valid. >> >> OK. That makes sense (even though I think it would make cutting and >> pasting somewhat awkward). > > Cutting and pasting is already potentially awkward, because we > rfc2047-quote in format-patch, too. But we can still get away without > quoting at all in regular "git log". The "Author:" lines, while > rfc822-looking do not have to be real header lines, and we know that > everything before the <> must be the name. > > So I think this is the patch we want: > > -- >8 -- > Subject: [PATCH] pretty: quote rfc822 specials in email addresses > > If somebody has a name that includes an rfc822 special, we > will output it literally in the "From:" header. This is > usually OK, but certain characters (like ".") are supposed > to be enclosed in double-quotes in a mail header. > > In practice, whether this matters may depend on your MUA. > Some MUAs will happily take in: > > From: Foo B. Bar <author@xxxxxxxxxxx> > > without quotes, and properly quote the "." when they send > the actual mail. Others may not, or may screw up harder > things like: > > From: Foo "The Baz" Bar <author@xxxxxxxxxxx> > > For example, mutt will strip the quotes, thinking they are > actual syntactic rfc822 quotes. > > So let's quote properly, and then (if necessary) we still > apply rfc2047 encoding on top of that, which should make all > MUAs happy. > > Signed-off-by: Jeff King <peff@xxxxxxxx> > --- > pretty.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++- > t/t4014-format-patch.sh | 42 ++++++++++++++++++++++++++++++++ > 2 files changed, 102 insertions(+), 1 deletions(-) > > diff --git a/pretty.c b/pretty.c > index e1d8a8f..8345485 100644 > --- a/pretty.c > +++ b/pretty.c > @@ -208,6 +208,58 @@ int has_non_ascii(const char *s) > return 0; > } > > +static int is_rfc822_special(char ch) > +{ > + switch (ch) { > + case '(': > + case ')': > + case '<': > + case '>': > + case '[': > + case ']': > + case ':': > + case ';': > + case '@': > + case ',': > + case '.': > + case '"': > + case '\\': > + return 1; > + default: > + return 0; > + } > +} > + > +static int has_rfc822_specials(const char *s, int len) > +{ > + int i; > + for (i = 0; i < len; i++) > + if (is_rfc822_special(s[i])) > + return 1; > + return 0; > +} > + > +static void add_rfc822_quoted(struct strbuf *out, const char *s, int len) > +{ > + int i; > + > + /* just a guess, we may have to also backslash-quote */ > + strbuf_grow(out, len + 2); > + > + strbuf_addch(out, '"'); > + for (i = 0; i < len; i++) { > + switch (s[i]) { > + case '"': > + case '\\': > + strbuf_addch(out, '\\'); > + /* fall through */ > + default: > + strbuf_addch(out, s[i]); > + } > + } > + strbuf_addch(out, '"'); > +} > + > static int is_rfc2047_special(char ch) > { > return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_')); > @@ -293,7 +345,14 @@ void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb, > name_tail--; > display_name_length = name_tail - line; > strbuf_addstr(sb, "From: "); > - add_rfc2047(sb, line, display_name_length, encoding); > + if (has_rfc822_specials(line, display_name_length)) { > + struct strbuf quoted = STRBUF_INIT; > + add_rfc822_quoted("ed, line, display_name_length); > + add_rfc2047(sb, quoted.buf, quoted.len, encoding); > + strbuf_release("ed); > + } > + else > + add_rfc2047(sb, line, display_name_length, encoding); > strbuf_add(sb, name_tail, namelen - display_name_length); > strbuf_addch(sb, '\n'); > } else { > diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh > index c3cdb52..dd406c4 100755 > --- a/t/t4014-format-patch.sh > +++ b/t/t4014-format-patch.sh > @@ -793,4 +793,46 @@ test_expect_success 'format-patch wraps extremely long headers (rfc2047)' ' > test_cmp expect subject > ' > > +check_author() { > + echo content >>file && > + git add file && > + GIT_AUTHOR_NAME=$1 git commit -m author-check && > + git format-patch --stdout -1 >patch && > + grep ^From: patch >actual && > + test_cmp expect actual > +} > + > +cat >expect <<'EOF' > +From: "Foo B. Bar" <author@xxxxxxxxxxx> > +EOF > +test_expect_success 'format-patch quotes dot in headers' ' > + check_author "Foo B. Bar" > +' > + > +cat >expect <<'EOF' > +From: "Foo \"The Baz\" Bar" <author@xxxxxxxxxxx> > +EOF > +test_expect_success 'format-patch quotes double-quote in headers' ' > + check_author "Foo \"The Baz\" Bar" > +' > + > +cat >expect <<'EOF' > +From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@xxxxxxxxxxx> > +EOF > +test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' ' > + check_author "FÃo B. Bar" > +' > + > +cat >expect <<'EOF' > +Subject: header with . in it > +EOF > +test_expect_success 'subject lines do not have 822 atom-quoting' ' > + echo content >>file && > + git add file && > + git commit -m "header with . in it" && > + git format-patch -k -1 --stdout >patch && > + grep ^Subject: patch >actual && > + test_cmp expect actual > +' > + > test_done -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html