@@ -24,6 +24,9 @@ import (
2424 "strings"
2525 "time"
2626 "unicode"
27+
28+ "golang.org/x/text/encoding/htmlindex"
29+ "golang.org/x/text/transform"
2730)
2831
2932const (
@@ -90,7 +93,7 @@ func handleAddressList(v []string) []string {
9093 for _ , a := range v {
9194 w := strings .Split (a , "," )
9295 for _ , addr := range w {
93- decodedAddr , err := ( & mime. WordDecoder {}) .DecodeHeader (strings .TrimSpace (addr ))
96+ decodedAddr , err := wordDecoder .DecodeHeader (strings .TrimSpace (addr ))
9497 if err == nil {
9598 res = append (res , decodedAddr )
9699 } else {
@@ -118,7 +121,7 @@ func NewEmailFromReader(r io.Reader) (*Email, error) {
118121 switch h {
119122 case "Subject" :
120123 e .Subject = v [0 ]
121- subj , err := ( & mime. WordDecoder {}) .DecodeHeader (e .Subject )
124+ subj , err := wordDecoder .DecodeHeader (e .Subject )
122125 if err == nil && len (subj ) > 0 {
123126 e .Subject = subj
124127 }
@@ -137,7 +140,7 @@ func NewEmailFromReader(r io.Reader) (*Email, error) {
137140 delete (hdrs , h )
138141 case "From" :
139142 e .From = v [0 ]
140- fr , err := ( & mime. WordDecoder {}) .DecodeHeader (e .From )
143+ fr , err := wordDecoder .DecodeHeader (e .From )
141144 if err == nil && len (fr ) > 0 {
142145 e .From = fr
143146 }
@@ -216,7 +219,7 @@ func parseMIMEParts(hs textproto.MIMEHeader, b io.Reader) ([]*part, error) {
216219 if _ , ok := p .Header ["Content-Type" ]; ! ok {
217220 p .Header .Set ("Content-Type" , defaultContentType )
218221 }
219- subct , _ , err := mime .ParseMediaType (p .Header .Get ("Content-Type" ))
222+ subct , subps , err := mime .ParseMediaType (p .Header .Get ("Content-Type" ))
220223 if err != nil {
221224 return ps , err
222225 }
@@ -232,6 +235,15 @@ func parseMIMEParts(hs textproto.MIMEHeader, b io.Reader) ([]*part, error) {
232235 const cte = "Content-Transfer-Encoding"
233236 if p .Header .Get (cte ) == "base64" {
234237 reader = base64 .NewDecoder (base64 .StdEncoding , reader )
238+
239+ reader = base64 .NewDecoder (base64 .StdEncoding , reader )
240+
241+ if strings .HasPrefix (subct , "text" ) && subps ["charset" ] != "" {
242+ transReader , err := wordDecoder .CharsetReader (subps ["charset" ], reader )
243+ if err == nil {
244+ reader = transReader
245+ }
246+ }
235247 }
236248 // Otherwise, just append the part to the list
237249 // Copy the part data into the buffer
@@ -807,3 +819,13 @@ func generateMessageID() (string, error) {
807819 msgid := fmt .Sprintf ("<%d.%d.%d@%s>" , t , pid , rint , h )
808820 return msgid , nil
809821}
822+
823+ var wordDecoder = & mime.WordDecoder {
824+ CharsetReader : func (charset string , input io.Reader ) (io.Reader , error ) {
825+ encoding , err := htmlindex .Get (charset )
826+ if err != nil {
827+ return nil , err
828+ }
829+ return transform .NewReader (input , encoding .NewDecoder ()), nil
830+ },
831+ }
0 commit comments