From: Hiroshi Ioka Date: Sat, 4 Mar 2017 10:47:19 +0000 (+0900) Subject: net/mail: ignore whitespace between adjacent 'encoded-word's X-Git-Tag: go1.9beta1~1259 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6491496d10c8e7e62f875c7781a2887564976b89;p=gostls13.git net/mail: ignore whitespace between adjacent 'encoded-word's rfc2047 says: White space between adjacent 'encoded-word's is not displayed. Although, mime package already have that feature, we cannot simply reuse that code, because there is a subtle difference in quoted-string handling. Fixes #19363 Change-Id: I754201aa3c6b701074ad78fe46818af5b96cbd00 Reviewed-on: https://go-review.googlesource.com/37811 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- diff --git a/src/net/mail/message.go b/src/net/mail/message.go index 702b765c34..6db8a397e9 100644 --- a/src/net/mail/message.go +++ b/src/net/mail/message.go @@ -387,6 +387,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) { debug.Printf("consumePhrase: [%s]", p.s) // phrase = 1*word var words []string + var isPrevEncoded bool for { // word = atom / quoted-string var word string @@ -394,6 +395,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) { if p.empty() { return "", errors.New("mail: missing phrase") } + isEncoded := false if p.peek() == '"' { // quoted-string word, err = p.consumeQuotedString() @@ -403,7 +405,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) { // than what RFC 5322 specifies. word, err = p.consumeAtom(true, true) if err == nil { - word, err = p.decodeRFC2047Word(word) + word, isEncoded, err = p.decodeRFC2047Word(word) } } @@ -411,7 +413,12 @@ func (p *addrParser) consumePhrase() (phrase string, err error) { break } debug.Printf("consumePhrase: consumed %q", word) - words = append(words, word) + if isPrevEncoded && isEncoded { + words[len(words)-1] += word + } else { + words = append(words, word) + } + isPrevEncoded = isEncoded } // Ignore any error if we got at least one word. if err != nil && len(words) == 0 { @@ -540,22 +547,23 @@ func (p *addrParser) len() int { return len(p.s) } -func (p *addrParser) decodeRFC2047Word(s string) (string, error) { +func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) { if p.dec != nil { - return p.dec.DecodeHeader(s) + word, err = p.dec.Decode(s) + } else { + word, err = rfc2047Decoder.Decode(s) } - dec, err := rfc2047Decoder.Decode(s) if err == nil { - return dec, nil + return word, true, nil } if _, ok := err.(charsetError); ok { - return s, err + return s, true, err } // Ignore invalid RFC 2047 encoded-word errors. - return s, nil + return s, false, nil } var rfc2047Decoder = mime.WordDecoder{ diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go index f0761ab09f..0ed36b02f8 100644 --- a/src/net/mail/message_test.go +++ b/src/net/mail/message_test.go @@ -235,6 +235,16 @@ func TestAddressParsing(t *testing.T) { }, }, }, + // RFC 2047 "Q"-encoded UTF-8 address with multiple encoded-words. + { + `=?utf-8?q?J=C3=B6rg?= =?utf-8?q?Doe?= `, + []*Address{ + { + Name: `JörgDoe`, + Address: "joerg@example.com", + }, + }, + }, // RFC 2047, Section 8. { `=?ISO-8859-1?Q?Andr=E9?= Pirard `,