mirror of
https://github.com/golang/go
synced 2024-11-20 02:14:46 -07:00
net/mail: parse cases when phrase has special chars without quotes
Updates #21018 Change-Id: I00b6667fb5fee78559a391815f58760a2baea90e Reviewed-on: https://go-review.googlesource.com/50911 Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Avelino <t@avelino.xxx> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
b0392159f6
commit
738acbc2f0
@ -14,6 +14,7 @@ Notable divergences:
|
||||
* The full range of spacing (the CFWS syntax element) is not supported,
|
||||
such as breaking addresses across lines.
|
||||
* No unicode normalization is performed.
|
||||
* Address with some RFC 5322 3.2.3 specials without quotes are parsed.
|
||||
*/
|
||||
package mail
|
||||
|
||||
@ -190,7 +191,7 @@ func (a *Address) String() string {
|
||||
// Add quotes if needed
|
||||
quoteLocal := false
|
||||
for i, r := range local {
|
||||
if isAtext(r, false) {
|
||||
if isAtext(r, false, false) {
|
||||
continue
|
||||
}
|
||||
if r == '.' {
|
||||
@ -482,20 +483,20 @@ Loop:
|
||||
|
||||
// consumeAtom parses an RFC 5322 atom at the start of p.
|
||||
// If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
|
||||
// If permissive is true, consumeAtom will not fail on
|
||||
// leading/trailing/double dots in the atom (see golang.org/issue/4938).
|
||||
// If permissive is true, consumeAtom will not fail on:
|
||||
// - leading/trailing/double dots in the atom (see golang.org/issue/4938)
|
||||
// - special characters (RFC 5322 3.2.3) except '<', '>' and '"' (see golang.org/issue/21018)
|
||||
func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err error) {
|
||||
i := 0
|
||||
|
||||
Loop:
|
||||
for {
|
||||
r, size := utf8.DecodeRuneInString(p.s[i:])
|
||||
|
||||
switch {
|
||||
case size == 1 && r == utf8.RuneError:
|
||||
return "", fmt.Errorf("mail: invalid utf-8 in address: %q", p.s)
|
||||
|
||||
case size == 0 || !isAtext(r, dot):
|
||||
case size == 0 || !isAtext(r, dot, permissive):
|
||||
break Loop
|
||||
|
||||
default:
|
||||
@ -580,12 +581,18 @@ func (e charsetError) Error() string {
|
||||
|
||||
// isAtext reports whether r is an RFC 5322 atext character.
|
||||
// If dot is true, period is included.
|
||||
func isAtext(r rune, dot bool) bool {
|
||||
// If permissive is true, RFC 5322 3.2.3 specials is included,
|
||||
// except '<', '>' and '"'.
|
||||
func isAtext(r rune, dot, permissive bool) bool {
|
||||
switch r {
|
||||
case '.':
|
||||
return dot
|
||||
|
||||
case '(', ')', '<', '>', '[', ']', ':', ';', '@', '\\', ',', '"': // RFC 5322 3.2.3. specials
|
||||
// RFC 5322 3.2.3. specials
|
||||
case '(', ')', '[', ']', ':', ';', '@', '\\', ',':
|
||||
return permissive
|
||||
|
||||
case '<', '>', '"':
|
||||
return false
|
||||
}
|
||||
return isVchar(r)
|
||||
|
@ -137,6 +137,8 @@ func TestAddressParsingError(t *testing.T) {
|
||||
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"},
|
||||
}
|
||||
|
||||
for i, tc := range mustErrTestCases {
|
||||
@ -175,6 +177,34 @@ func TestAddressParsing(t *testing.T) {
|
||||
Address: "john.q.public@example.com",
|
||||
}},
|
||||
},
|
||||
{
|
||||
`"John (middle) Doe" <jdoe@machine.example>`,
|
||||
[]*Address{{
|
||||
Name: "John (middle) Doe",
|
||||
Address: "jdoe@machine.example",
|
||||
}},
|
||||
},
|
||||
{
|
||||
`John (middle) Doe <jdoe@machine.example>`,
|
||||
[]*Address{{
|
||||
Name: "John (middle) Doe",
|
||||
Address: "jdoe@machine.example",
|
||||
}},
|
||||
},
|
||||
{
|
||||
`John !@M@! Doe <jdoe@machine.example>`,
|
||||
[]*Address{{
|
||||
Name: "John !@M@! Doe",
|
||||
Address: "jdoe@machine.example",
|
||||
}},
|
||||
},
|
||||
{
|
||||
`"John <middle> Doe" <jdoe@machine.example>`,
|
||||
[]*Address{{
|
||||
Name: "John <middle> Doe",
|
||||
Address: "jdoe@machine.example",
|
||||
}},
|
||||
},
|
||||
{
|
||||
`Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>`,
|
||||
[]*Address{
|
||||
@ -203,6 +233,14 @@ func TestAddressParsing(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
// RFC 5322, Appendix A.6.1
|
||||
{
|
||||
`Joe Q. Public <john.q.public@example.com>`,
|
||||
[]*Address{{
|
||||
Name: "Joe Q. Public",
|
||||
Address: "john.q.public@example.com",
|
||||
}},
|
||||
},
|
||||
// RFC 5322, Appendix A.1.3
|
||||
// TODO(dsymonds): Group addresses.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user