aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net/mail
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2016-02-03 21:58:02 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-02-03 21:58:02 +0000
commitf98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch)
tree2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/net/mail
parentb081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff)
downloadgcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.zip
gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.gz
gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.bz2
libgo: Update to go1.6rc1.
Reviewed-on: https://go-review.googlesource.com/19200 From-SVN: r233110
Diffstat (limited to 'libgo/go/net/mail')
-rw-r--r--libgo/go/net/mail/message.go23
-rw-r--r--libgo/go/net/mail/message_test.go68
2 files changed, 85 insertions, 6 deletions
diff --git a/libgo/go/net/mail/message.go b/libgo/go/net/mail/message.go
index 266ac50..923630c 100644
--- a/libgo/go/net/mail/message.go
+++ b/libgo/go/net/mail/message.go
@@ -234,6 +234,12 @@ func (a *Address) String() string {
return b.String()
}
+ // Text in an encoded-word in a display-name must not contain certain
+ // characters like quotes or parentheses (see RFC 2047 section 5.3).
+ // When this is the case encode the name using base64 encoding.
+ if strings.ContainsAny(a.Name, "\"#$%&'(),.:;<>@[]^`{|}~") {
+ return mime.BEncoding.Encode("utf-8", a.Name) + " " + s
+ }
return mime.QEncoding.Encode("utf-8", a.Name) + " " + s
}
@@ -386,10 +392,9 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
// We actually parse dot-atom here to be more permissive
// than what RFC 5322 specifies.
word, err = p.consumeAtom(true, true)
- }
-
- if err == nil {
- word, err = p.decodeRFC2047Word(word)
+ if err == nil {
+ word, err = p.decodeRFC2047Word(word)
+ }
}
if err != nil {
@@ -442,17 +447,25 @@ Loop:
return string(qsb), nil
}
+var errNonASCII = errors.New("mail: unencoded non-ASCII text in address")
+
// 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).
func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err error) {
- if !isAtext(p.peek(), false) {
+ if c := p.peek(); !isAtext(c, false) {
+ if c > 127 {
+ return "", errNonASCII
+ }
return "", errors.New("mail: invalid string")
}
i := 1
for ; i < p.len() && isAtext(p.s[i], dot); i++ {
}
+ if i < p.len() && p.s[i] > 127 {
+ return "", errNonASCII
+ }
atom, p.s = string(p.s[:i]), p.s[i:]
if !permissive {
if strings.HasPrefix(atom, ".") {
diff --git a/libgo/go/net/mail/message_test.go b/libgo/go/net/mail/message_test.go
index 1b42274..4e718e2 100644
--- a/libgo/go/net/mail/message_test.go
+++ b/libgo/go/net/mail/message_test.go
@@ -127,6 +127,14 @@ func TestAddressParsingError(t *testing.T) {
}
}
+func TestAddressParsingErrorUnquotedNonASCII(t *testing.T) {
+ const txt = "µ <micro@example.net>"
+ _, err := ParseAddress(txt)
+ if err == nil || !strings.Contains(err.Error(), "unencoded non-ASCII text in address") {
+ t.Errorf(`mail.ParseAddress(%q) err: %q, want ".*unencoded non-ASCII text in address.*"`, txt, err)
+ }
+}
+
func TestAddressParsing(t *testing.T) {
tests := []struct {
addrsStr string
@@ -449,7 +457,7 @@ func TestAddressParser(t *testing.T) {
}
}
-func TestAddressFormatting(t *testing.T) {
+func TestAddressString(t *testing.T) {
tests := []struct {
addr *Address
exp string
@@ -491,11 +499,40 @@ func TestAddressFormatting(t *testing.T) {
&Address{Name: "Rob", Address: "@"},
`"Rob" <@>`,
},
+ {
+ &Address{Name: "Böb, Jacöb", Address: "bob@example.com"},
+ `=?utf-8?b?QsO2YiwgSmFjw7Zi?= <bob@example.com>`,
+ },
+ {
+ &Address{Name: "=??Q?x?=", Address: "hello@world.com"},
+ `"=??Q?x?=" <hello@world.com>`,
+ },
+ {
+ &Address{Name: "=?hello", Address: "hello@world.com"},
+ `"=?hello" <hello@world.com>`,
+ },
+ {
+ &Address{Name: "world?=", Address: "hello@world.com"},
+ `"world?=" <hello@world.com>`,
+ },
}
for _, test := range tests {
s := test.addr.String()
if s != test.exp {
t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp)
+ continue
+ }
+
+ // Check round-trip.
+ if test.addr.Address != "" && test.addr.Address != "@" {
+ a, err := ParseAddress(test.exp)
+ if err != nil {
+ t.Errorf("ParseAddress(%#q): %v", test.exp, err)
+ continue
+ }
+ if a.Name != test.addr.Name || a.Address != test.addr.Address {
+ t.Errorf("ParseAddress(%#q) = %#v, want %#v", test.exp, a, test.addr)
+ }
}
}
}
@@ -586,3 +623,32 @@ func TestAddressParsingAndFormatting(t *testing.T) {
}
}
+
+func TestAddressFormattingAndParsing(t *testing.T) {
+ tests := []*Address{
+ {Name: "@lïce", Address: "alice@example.com"},
+ {Name: "Böb O'Connor", Address: "bob@example.com"},
+ {Name: "???", Address: "bob@example.com"},
+ {Name: "Böb ???", Address: "bob@example.com"},
+ {Name: "Böb (Jacöb)", Address: "bob@example.com"},
+ {Name: "à#$%&'(),.:;<>@[]^`{|}~'", Address: "bob@example.com"},
+ // https://golang.org/issue/11292
+ {Name: "\"\\\x1f,\"", Address: "0@0"},
+ // https://golang.org/issue/12782
+ {Name: "naé, mée", Address: "test.mail@gmail.com"},
+ }
+
+ for i, test := range tests {
+ parsed, err := ParseAddress(test.String())
+ if err != nil {
+ t.Errorf("test #%d: ParseAddr(%q) error: %v", i, test.String(), err)
+ continue
+ }
+ if parsed.Name != test.Name {
+ t.Errorf("test #%d: Parsed name = %q; want %q", i, parsed.Name, test.Name)
+ }
+ if parsed.Address != test.Address {
+ t.Errorf("test #%d: Parsed address = %q; want %q", i, parsed.Address, test.Address)
+ }
+ }
+}