1
0
mirror of https://github.com/golang/go synced 2024-10-03 03:11:21 -06: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)
p.skipSpace()
if !p.skipCfws() {
return nil, errors.New("mail: misformatted parenthetical comment")
}
if p.empty() {
break
}
@ -270,7 +272,9 @@ func (p *addrParser) parseSingleAddress() (*Address, error) {
if err != nil {
return nil, err
}
p.skipSpace()
if !p.skipCfws() {
return nil, errors.New("mail: misformatted parenthetical comment")
}
if !p.empty() {
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)
}
// 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) {
if p.dec != nil {
word, err = p.dec.Decode(s)

View File

@ -129,16 +129,17 @@ func TestAddressParsingError(t *testing.T) {
text string
wantErrText string
}{
0: {"=?iso-8859-2?Q?Bogl=E1rka_Tak=E1cs?= <unknown@gmail.com>", "charset not supported"},
1: {"a@gmail.com b@gmail.com", "expected single address"},
2: {string([]byte{0xed, 0xa0, 0x80}) + " <micro@example.net>", "invalid utf-8 in address"},
3: {"\"" + string([]byte{0xed, 0xa0, 0x80}) + "\" <half-surrogate@example.com>", "invalid utf-8 in quoted-string"},
4: {"\"\\" + string([]byte{0x80}) + "\" <escaped-invalid-unicode@example.net>", "invalid utf-8 in quoted-string"},
5: {"\"\x00\" <null@example.net>", "bad character in quoted-string"},
6: {"\"\\\x00\" <escaped-null@example.net>", "bad character in quoted-string"},
7: {"John Doe", "no angle-addr"},
8: {`<jdoe#machine.example>`, "missing @ in addr-spec"},
9: {`John <middle> Doe <jdoe@machine.example>`, "missing @ in addr-spec"},
0: {"=?iso-8859-2?Q?Bogl=E1rka_Tak=E1cs?= <unknown@gmail.com>", "charset not supported"},
1: {"a@gmail.com b@gmail.com", "expected single address"},
2: {string([]byte{0xed, 0xa0, 0x80}) + " <micro@example.net>", "invalid utf-8 in address"},
3: {"\"" + string([]byte{0xed, 0xa0, 0x80}) + "\" <half-surrogate@example.com>", "invalid utf-8 in quoted-string"},
4: {"\"\\" + string([]byte{0x80}) + "\" <escaped-invalid-unicode@example.net>", "invalid utf-8 in quoted-string"},
5: {"\"\x00\" <null@example.net>", "bad character in quoted-string"},
6: {"\"\\\x00\" <escaped-null@example.net>", "bad character in quoted-string"},
7: {"John Doe", "no angle-addr"},
8: {`<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 {
@ -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 {
if len(test.exp) == 1 {