From 2cb265d16c611aae56fd3f3ce87279a1f52f925a Mon Sep 17 00:00:00 2001 From: Alexandre Cesaro Date: Tue, 20 Oct 2015 17:30:21 +0200 Subject: [PATCH] net/mail: use base64 encoding when needed in Address.String() When the name of an Address contains non-ASCII characters, Address.String() used mime.QEncoding to encode the name. However certain characters are forbidden when an encoded-word is in a phrase context (see RFC 2047 section 5.3) and these characters are not encoded by mime.QEncoding. In this case we now use mime.BEncoding (base64 encoding) so that forbidden characters are also encoded. Fixes #11292 Change-Id: I52db98b41ece439295e97d7e94c8190426f499c2 Reviewed-on: https://go-review.googlesource.com/16012 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/net/mail/message.go | 6 ++++++ src/net/mail/message_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/net/mail/message.go b/src/net/mail/message.go index 01290bc65b..571c95ddc9 100644 --- a/src/net/mail/message.go +++ b/src/net/mail/message.go @@ -234,6 +234,12 @@ func (a *Address) String() string { return b.String() } + // Text in an encoded-word in a display-name must not contain certain + // characters like quotes or parentheses (see RFC 2047 section 5.3). + // When this is the case encode the name using base64 encoding. + if strings.ContainsAny(a.Name, "\"#$%&'(),.:;<>@[]^`{|}~") { + return mime.BEncoding.Encode("utf-8", a.Name) + " " + s + } return mime.QEncoding.Encode("utf-8", a.Name) + " " + s } diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go index e05af6c6ba..9fd7923c34 100644 --- a/src/net/mail/message_test.go +++ b/src/net/mail/message_test.go @@ -499,6 +499,10 @@ func TestAddressFormatting(t *testing.T) { &Address{Name: "Rob", Address: "@"}, `"Rob" <@>`, }, + { + &Address{Name: "Böb, Jacöb", Address: "bob@example.com"}, + `=?utf-8?b?QsO2YiwgSmFjw7Zi?= `, + }, } for _, test := range tests { s := test.addr.String() @@ -594,3 +598,32 @@ func TestAddressParsingAndFormatting(t *testing.T) { } } + +func TestAddressFormattingAndParsing(t *testing.T) { + tests := []*Address{ + &Address{Name: "@lïce", Address: "alice@example.com"}, + &Address{Name: "Böb O'Connor", Address: "bob@example.com"}, + &Address{Name: "???", Address: "bob@example.com"}, + &Address{Name: "Böb ???", Address: "bob@example.com"}, + &Address{Name: "Böb (Jacöb)", Address: "bob@example.com"}, + &Address{Name: "à#$%&'(),.:;<>@[]^`{|}~'", Address: "bob@example.com"}, + // https://golang.org/issue/11292 + &Address{Name: "\"\\\x1f,\"", Address: "0@0"}, + // https://golang.org/issue/12782 + &Address{Name: "naé, mée", Address: "test.mail@gmail.com"}, + } + + for _, test := range tests { + parsed, err := ParseAddress(test.String()) + if err != nil { + t.Errorf("ParseAddr(%q) error: %v", test.String(), err) + continue + } + if parsed.Name != test.Name { + t.Errorf("Parsed name = %q; want %q", parsed.Name, test.Name) + } + if parsed.Address != test.Address { + t.Errorf("Parsed address = %q; want %q", parsed.Address, test.Address) + } + } +} -- 2.50.0