}
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
}
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) {