aboutsummaryrefslogtreecommitdiff
path: root/src/net/mail/message.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/mail/message.go')
-rw-r--r--src/net/mail/message.go103
1 files changed, 3 insertions, 100 deletions
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
index 19aa888d87..71fe74b9ca 100644
--- a/src/net/mail/message.go
+++ b/src/net/mail/message.go
@@ -18,17 +18,14 @@ package mail
import (
"bufio"
"bytes"
- "encoding/base64"
"errors"
"fmt"
+ "internal/mime"
"io"
- "io/ioutil"
"log"
"net/textproto"
- "strconv"
"strings"
"time"
- "unicode"
)
var debug = debugT(false)
@@ -180,21 +177,7 @@ func (a *Address) String() string {
return b.String()
}
- // UTF-8 "Q" encoding
- b := bytes.NewBufferString("=?utf-8?q?")
- for i := 0; i < len(a.Name); i++ {
- switch c := a.Name[i]; {
- case c == ' ':
- b.WriteByte('_')
- case isVchar(c) && c != '=' && c != '?' && c != '_':
- b.WriteByte(c)
- default:
- fmt.Fprintf(b, "=%02X", c)
- }
- }
- b.WriteString("?= ")
- b.WriteString(s)
- return b.String()
+ return mime.EncodeWord(a.Name) + " " + s
}
type addrParser []byte
@@ -352,7 +335,7 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
// RFC 2047 encoded-word starts with =?, ends with ?=, and has two other ?s.
if err == nil && strings.HasPrefix(word, "=?") && strings.HasSuffix(word, "?=") && strings.Count(word, "?") == 4 {
- word, err = decodeRFC2047Word(word)
+ word, err = mime.DecodeWord(word)
}
if err != nil {
@@ -440,86 +423,6 @@ func (p *addrParser) len() int {
return len(*p)
}
-func decodeRFC2047Word(s string) (string, error) {
- fields := strings.Split(s, "?")
- if len(fields) != 5 || fields[0] != "=" || fields[4] != "=" {
- return "", errors.New("address not RFC 2047 encoded")
- }
- charset, enc := strings.ToLower(fields[1]), strings.ToLower(fields[2])
- if charset != "us-ascii" && charset != "iso-8859-1" && charset != "utf-8" {
- return "", fmt.Errorf("charset not supported: %q", charset)
- }
-
- in := bytes.NewBufferString(fields[3])
- var r io.Reader
- switch enc {
- case "b":
- r = base64.NewDecoder(base64.StdEncoding, in)
- case "q":
- r = qDecoder{r: in}
- default:
- return "", fmt.Errorf("RFC 2047 encoding not supported: %q", enc)
- }
-
- dec, err := ioutil.ReadAll(r)
- if err != nil {
- return "", err
- }
-
- switch charset {
- case "us-ascii":
- b := new(bytes.Buffer)
- for _, c := range dec {
- if c >= 0x80 {
- b.WriteRune(unicode.ReplacementChar)
- } else {
- b.WriteRune(rune(c))
- }
- }
- return b.String(), nil
- case "iso-8859-1":
- b := new(bytes.Buffer)
- for _, c := range dec {
- b.WriteRune(rune(c))
- }
- return b.String(), nil
- case "utf-8":
- return string(dec), nil
- }
- panic("unreachable")
-}
-
-type qDecoder struct {
- r io.Reader
- scratch [2]byte
-}
-
-func (qd qDecoder) Read(p []byte) (n int, err error) {
- // This method writes at most one byte into p.
- if len(p) == 0 {
- return 0, nil
- }
- if _, err := qd.r.Read(qd.scratch[:1]); err != nil {
- return 0, err
- }
- switch c := qd.scratch[0]; {
- case c == '=':
- if _, err := io.ReadFull(qd.r, qd.scratch[:2]); err != nil {
- return 0, err
- }
- x, err := strconv.ParseInt(string(qd.scratch[:2]), 16, 64)
- if err != nil {
- return 0, fmt.Errorf("mail: invalid RFC 2047 encoding: %q", qd.scratch[:2])
- }
- p[0] = byte(x)
- case c == '_':
- p[0] = ' '
- default:
- p[0] = c
- }
- return 1, nil
-}
-
var atextChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789" +