1
0
mirror of https://github.com/golang/go synced 2024-11-20 05:14:41 -07:00

net/mail: skip trailing comment while parsing email

The existing implementation doesn't handle
comment constructions in email address.
So addresses that are consistent with RFC 5322
don't parse at all.

Fixes #21257

Change-Id: Iae3ba951dfb26b7cf0e1885a680bbceb9123d6d5
Reviewed-on: https://go-review.googlesource.com/53550
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Minaev Mike 2017-08-07 08:22:21 +00:00 committed by Ian Lance Taylor
parent ff3123d1f6
commit 8598396d81
2 changed files with 81 additions and 12 deletions

View File

@ -254,7 +254,9 @@ func (p *addrParser) parseAddressList() ([]*Address, error) {
} }
list = append(list, addr) list = append(list, addr)
p.skipSpace() if !p.skipCfws() {
return nil, errors.New("mail: misformatted parenthetical comment")
}
if p.empty() { if p.empty() {
break break
} }
@ -270,7 +272,9 @@ func (p *addrParser) parseSingleAddress() (*Address, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
p.skipSpace() if !p.skipCfws() {
return nil, errors.New("mail: misformatted parenthetical comment")
}
if !p.empty() { if !p.empty() {
return nil, fmt.Errorf("mail: expected single address, got %q", p.s) return nil, fmt.Errorf("mail: expected single address, got %q", p.s)
} }
@ -548,6 +552,47 @@ func (p *addrParser) len() int {
return len(p.s) return len(p.s)
} }
// skipCfws skips CFWS as defined in RFC5322.
func (p *addrParser) skipCfws() bool {
p.skipSpace()
for {
if !p.consume('(') {
break
}
if !p.skipComment() {
return false
}
p.skipSpace()
}
return true
}
func (p *addrParser) skipComment() bool {
// '(' already consumed.
depth := 1
for {
if p.empty() || depth == 0 {
break
}
if p.peek() == '\\' && p.len() > 1 {
p.s = p.s[1:]
} else if p.peek() == '(' {
depth++
} else if p.peek() == ')' {
depth--
}
p.s = p.s[1:]
}
return depth == 0
}
func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) { func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) {
if p.dec != nil { if p.dec != nil {
word, err = p.dec.Decode(s) word, err = p.dec.Decode(s)

View File

@ -139,6 +139,7 @@ func TestAddressParsingError(t *testing.T) {
7: {"John Doe", "no angle-addr"}, 7: {"John Doe", "no angle-addr"},
8: {`<jdoe#machine.example>`, "missing @ in addr-spec"}, 8: {`<jdoe#machine.example>`, "missing @ in addr-spec"},
9: {`John <middle> Doe <jdoe@machine.example>`, "missing @ in addr-spec"}, 9: {`John <middle> Doe <jdoe@machine.example>`, "missing @ in addr-spec"},
10: {"cfws@example.com (", "misformatted parenthetical comment"},
} }
for i, tc := range mustErrTestCases { for i, tc := range mustErrTestCases {
@ -374,6 +375,29 @@ func TestAddressParsing(t *testing.T) {
}, },
}, },
}, },
// CFWS
{
`cfws@example.com (CFWS (cfws)) (another comment)`,
[]*Address{
{
Name: "",
Address: "cfws@example.com",
},
},
},
{
`cfws@example.com () (another comment), cfws2@example.com (another)`,
[]*Address{
{
Name: "",
Address: "cfws@example.com",
},
{
Name: "",
Address: "cfws2@example.com",
},
},
},
} }
for _, test := range tests { for _, test := range tests {
if len(test.exp) == 1 { if len(test.exp) == 1 {