1
0
mirror of https://github.com/golang/go synced 2024-09-29 13:14:28 -06:00

net/mail: improve detection of charset errors

The detection of the "unknown charset" case was too tailored
to one specific address parser. Make it generalize, so that custom
address parsers behave the same way as the default one
for character sets they do not handle.

Fixes #41625.

Change-Id: I347d4bb6844d0a1f23e908b776d21e8be5af3874
Reviewed-on: https://go-review.googlesource.com/c/go/+/283632
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Russ Cox 2021-01-13 10:53:48 -05:00 committed by Gopher Robot
parent f25631b490
commit 2bbf383774
2 changed files with 40 additions and 5 deletions

View File

@ -745,17 +745,41 @@ func (p *addrParser) consumeComment() (string, bool) {
}
func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) {
if p.dec != nil {
word, err = p.dec.Decode(s)
} else {
word, err = rfc2047Decoder.Decode(s)
dec := p.dec
if dec == nil {
dec = &rfc2047Decoder
}
// Substitute our own CharsetReader function so that we can tell
// whether an error from the Decode method was due to the
// CharsetReader (meaning the charset is invalid).
// We used to look for the charsetError type in the error result,
// but that behaves badly with CharsetReaders other than the
// one in rfc2047Decoder.
adec := *dec
charsetReaderError := false
adec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
if dec.CharsetReader == nil {
charsetReaderError = true
return nil, charsetError(charset)
}
r, err := dec.CharsetReader(charset, input)
if err != nil {
charsetReaderError = true
}
return r, err
}
word, err = adec.Decode(s)
if err == nil {
return word, true, nil
}
if _, ok := err.(charsetError); ok {
// If the error came from the character set reader
// (meaning the character set itself is invalid
// but the decoding worked fine until then),
// return the original text and the error,
// with isEncoded=true.
if charsetReaderError {
return s, true, err
}

View File

@ -344,6 +344,17 @@ func TestAddressParsingError(t *testing.T) {
t.Errorf(`mail.ParseAddress(%q) #%d want %q, got %v`, tc.text, i, tc.wantErrText, err)
}
}
t.Run("CustomWordDecoder", func(t *testing.T) {
p := &AddressParser{WordDecoder: &mime.WordDecoder{}}
for i, tc := range mustErrTestCases {
_, err := p.Parse(tc.text)
if err == nil || !strings.Contains(err.Error(), tc.wantErrText) {
t.Errorf(`p.Parse(%q) #%d want %q, got %v`, tc.text, i, tc.wantErrText, err)
}
}
})
}
func TestAddressParsing(t *testing.T) {