mime: Export RFC 2047 code

Fixes #4943
Fixes #4687
Fixes #7079

Change-Id: Ia96f07d650a3af935cd75fd7e3253f4af2977429
Reviewed-on: https://go-review.googlesource.com/7890
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Alexandre Cesaro 2015-03-20 10:22:55 +01:00 committed by Brad Fitzpatrick
parent e3a9a08a0b
commit 2b03610842
5 changed files with 638 additions and 166 deletions

View file

@ -20,9 +20,9 @@ import (
"bytes"
"errors"
"fmt"
"internal/mime"
"io"
"log"
"mime"
"net/textproto"
"strings"
"time"
@ -177,7 +177,7 @@ func (a *Address) String() string {
return b.String()
}
return mime.EncodeWord(a.Name) + " " + s
return mime.QEncoding.Encode("utf-8", a.Name) + " " + s
}
type addrParser []byte
@ -333,9 +333,8 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
word, err = p.consumeAtom(true)
}
// 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 = mime.DecodeWord(word)
if err == nil {
word, err = decodeRFC2047Word(word)
}
if err != nil {
@ -423,6 +422,32 @@ func (p *addrParser) len() int {
return len(*p)
}
func decodeRFC2047Word(s string) (string, error) {
dec, err := rfc2047Decoder.Decode(s)
if err == nil {
return dec, nil
}
if _, ok := err.(charsetError); ok {
return s, err
}
// Ignore invalid RFC 2047 encoded-word errors.
return s, nil
}
var rfc2047Decoder = mime.WordDecoder{
CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
return nil, charsetError(charset)
},
}
type charsetError string
func (e charsetError) Error() string {
return fmt.Sprintf("charset not supported: %q", string(e))
}
var atextChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789" +