Fix header decoding

Email headers can be encoded with different charsets, which is signalled
using a special character sequence. The go-message package provides two
different methods for accessing header values, Get(key) (actually
inherited from the embedded textproto.Header) which returns the raw
header value and Text(key), which returns the header's value decoded as
UTF-8.

Before, in the maildir backend, we were using the Get method which
sometimes resulted in encoded headers being displayed in the UI. This
patch replaces the incorrect usage of Get() with Text().
This commit is contained in:
Ben Burwell 2019-07-15 10:30:20 -04:00 committed by Drew DeVault
parent 8bb115dbae
commit eb0481b9cc

View file

@ -7,7 +7,6 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"mime/quotedprintable" "mime/quotedprintable"
gomail "net/mail"
"strings" "strings"
"github.com/emersion/go-maildir" "github.com/emersion/go-maildir"
@ -88,7 +87,7 @@ func (m Message) MessageInfo() (*models.MessageInfo, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get structure: %v", err) return nil, fmt.Errorf("could not get structure: %v", err)
} }
env, err := parseEnvelope(&msg.Header) env, err := parseEnvelope(&mail.Header{msg.Header})
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get envelope: %v", err) return nil, fmt.Errorf("could not get envelope: %v", err)
} }
@ -237,8 +236,8 @@ func parseEntityStructure(e *message.Entity) (*models.BodyStructure, error) {
return &body, nil return &body, nil
} }
func parseEnvelope(h *message.Header) (*models.Envelope, error) { func parseEnvelope(h *mail.Header) (*models.Envelope, error) {
date, err := gomail.ParseDate(h.Get("date")) date, err := h.Date()
if err != nil { if err != nil {
return nil, fmt.Errorf("could not parse date header: %v", err) return nil, fmt.Errorf("could not parse date header: %v", err)
} }
@ -258,10 +257,18 @@ func parseEnvelope(h *message.Header) (*models.Envelope, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("could not read bcc address: %v", err) return nil, fmt.Errorf("could not read bcc address: %v", err)
} }
subj, err := h.Subject()
if err != nil {
return nil, fmt.Errorf("could not read subject: %v", err)
}
msgID, err := h.Text("message-id")
if err != nil {
return nil, fmt.Errorf("could not read message id: %v", err)
}
return &models.Envelope{ return &models.Envelope{
Date: date, Date: date,
Subject: h.Get("subject"), Subject: subj,
MessageId: h.Get("message-id"), MessageId: msgID,
From: from, From: from,
To: to, To: to,
Cc: cc, Cc: cc,
@ -269,15 +276,11 @@ func parseEnvelope(h *message.Header) (*models.Envelope, error) {
}, nil }, nil
} }
func parseAddressList(h *message.Header, key string) ([]*models.Address, error) { func parseAddressList(h *mail.Header, key string) ([]*models.Address, error) {
var converted []*models.Address var converted []*models.Address
hdr := h.Get(key) addrs, err := h.AddressList(key)
if strings.TrimSpace(hdr) == "" {
return converted, nil
}
addrs, err := gomail.ParseAddressList(hdr)
if err != nil { if err != nil {
if strings.Index(hdr, "@") < 0 { if hdr, err := h.Text(key); err != nil && strings.Index(hdr, "@") < 0 {
return []*models.Address{&models.Address{ return []*models.Address{&models.Address{
Name: hdr, Name: hdr,
}}, nil }}, nil