Commit 6491496d authored by Hiroshi Ioka's avatar Hiroshi Ioka Committed by Ian Lance Taylor

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/37811Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 9207a743
...@@ -387,6 +387,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) { ...@@ -387,6 +387,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
debug.Printf("consumePhrase: [%s]", p.s) debug.Printf("consumePhrase: [%s]", p.s)
// phrase = 1*word // phrase = 1*word
var words []string var words []string
var isPrevEncoded bool
for { for {
// word = atom / quoted-string // word = atom / quoted-string
var word string var word string
...@@ -394,6 +395,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) { ...@@ -394,6 +395,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
if p.empty() { if p.empty() {
return "", errors.New("mail: missing phrase") return "", errors.New("mail: missing phrase")
} }
isEncoded := false
if p.peek() == '"' { if p.peek() == '"' {
// quoted-string // quoted-string
word, err = p.consumeQuotedString() word, err = p.consumeQuotedString()
...@@ -403,7 +405,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) { ...@@ -403,7 +405,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
// than what RFC 5322 specifies. // than what RFC 5322 specifies.
word, err = p.consumeAtom(true, true) word, err = p.consumeAtom(true, true)
if err == nil { 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) { ...@@ -411,7 +413,12 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
break break
} }
debug.Printf("consumePhrase: consumed %q", word) 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. // Ignore any error if we got at least one word.
if err != nil && len(words) == 0 { if err != nil && len(words) == 0 {
...@@ -540,22 +547,23 @@ func (p *addrParser) len() int { ...@@ -540,22 +547,23 @@ func (p *addrParser) len() int {
return len(p.s) 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 { 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 { if err == nil {
return dec, nil return word, true, nil
} }
if _, ok := err.(charsetError); ok { if _, ok := err.(charsetError); ok {
return s, err return s, true, err
} }
// Ignore invalid RFC 2047 encoded-word errors. // Ignore invalid RFC 2047 encoded-word errors.
return s, nil return s, false, nil
} }
var rfc2047Decoder = mime.WordDecoder{ var rfc2047Decoder = mime.WordDecoder{
......
...@@ -235,6 +235,16 @@ func TestAddressParsing(t *testing.T) { ...@@ -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?= <joerg@example.com>`,
[]*Address{
{
Name: `JörgDoe`,
Address: "joerg@example.com",
},
},
},
// RFC 2047, Section 8. // RFC 2047, Section 8.
{ {
`=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>`, `=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>`,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment