mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-15 14:56:42 +00:00
fix: unhandled charset in header
This commit is contained in:
@ -27,6 +27,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/pkg/message/parser"
|
||||
pmmime "github.com/ProtonMail/proton-bridge/pkg/mime"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
"github.com/emersion/go-message"
|
||||
"github.com/emersion/go-textwrapper"
|
||||
@ -374,60 +375,57 @@ func parseMessageHeader(m *pmapi.Message, h message.Header) error { // nolint[fu
|
||||
}
|
||||
m.Header = mimeHeader
|
||||
|
||||
fields := h.Fields()
|
||||
|
||||
for fields.Next() {
|
||||
text, err := fields.Text()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch strings.ToLower(fields.Key()) {
|
||||
if err := forEachDecodedHeaderField(h, func(key, val string) error {
|
||||
switch strings.ToLower(key) {
|
||||
case "subject":
|
||||
m.Subject = text
|
||||
m.Subject = val
|
||||
|
||||
case "from":
|
||||
sender, err := mail.ParseAddress(text)
|
||||
sender, err := mail.ParseAddress(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Sender = sender
|
||||
|
||||
case "to":
|
||||
toList, err := mail.ParseAddressList(text)
|
||||
toList, err := mail.ParseAddressList(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.ToList = toList
|
||||
|
||||
case "reply-to":
|
||||
replyTos, err := mail.ParseAddressList(text)
|
||||
replyTos, err := mail.ParseAddressList(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.ReplyTos = replyTos
|
||||
|
||||
case "cc":
|
||||
ccList, err := mail.ParseAddressList(text)
|
||||
ccList, err := mail.ParseAddressList(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.CCList = ccList
|
||||
|
||||
case "bcc":
|
||||
bccList, err := mail.ParseAddressList(text)
|
||||
bccList, err := mail.ParseAddressList(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.BCCList = bccList
|
||||
|
||||
case "date":
|
||||
date, err := mail.ParseDate(text)
|
||||
date, err := mail.ParseDate(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Time = date.Unix()
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -471,18 +469,37 @@ func parseAttachment(h message.Header) (*pmapi.Attachment, error) {
|
||||
return att, nil
|
||||
}
|
||||
|
||||
func toMailHeader(h message.Header) (mail.Header, error) {
|
||||
mimeHeader := make(mail.Header)
|
||||
|
||||
func forEachDecodedHeaderField(h message.Header, fn func(string, string) error) error {
|
||||
fields := h.Fields()
|
||||
|
||||
for fields.Next() {
|
||||
text, err := fields.Text()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !message.IsUnknownCharset(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if text, err = pmmime.DecodeHeader(fields.Value()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
mimeHeader[fields.Key()] = []string{text}
|
||||
if err := fn(fields.Key(), text); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func toMailHeader(h message.Header) (mail.Header, error) {
|
||||
mimeHeader := make(mail.Header)
|
||||
|
||||
if err := forEachDecodedHeaderField(h, func(key, val string) error {
|
||||
mimeHeader[key] = []string{val}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mimeHeader, nil
|
||||
@ -491,15 +508,11 @@ func toMailHeader(h message.Header) (mail.Header, error) {
|
||||
func toMIMEHeader(h message.Header) (textproto.MIMEHeader, error) {
|
||||
mimeHeader := make(textproto.MIMEHeader)
|
||||
|
||||
fields := h.Fields()
|
||||
|
||||
for fields.Next() {
|
||||
text, err := fields.Text()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mimeHeader[fields.Key()] = []string{text}
|
||||
if err := forEachDecodedHeaderField(h, func(key, val string) error {
|
||||
mimeHeader[key] = []string{val}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mimeHeader, nil
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
Mime-Version: 1.0
|
||||
From: Sender <sender@pm.me>
|
||||
To: Receiver <receiver@pm.me>
|
||||
Content-Type: multipart/mixed; boundary=longrandomstring
|
||||
|
||||
@ -75,6 +75,38 @@ func TestParseTextPlainLatin1(t *testing.T) {
|
||||
assert.Len(t, attReaders, 0)
|
||||
}
|
||||
|
||||
func TestParseTextPlainUTF8Subject(t *testing.T) {
|
||||
f := getFileReader("text_plain_utf8_subject.eml")
|
||||
|
||||
m, _, plainBody, attReaders, err := Parse(f, "", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, `"Sender" <sender@pm.me>`, m.Sender.String())
|
||||
assert.Equal(t, `"Receiver" <receiver@pm.me>`, m.ToList[0].String())
|
||||
assert.Equal(t, `汉字汉字汉`, m.Subject)
|
||||
|
||||
assert.Equal(t, "body", m.Body)
|
||||
assert.Equal(t, "body", plainBody)
|
||||
|
||||
assert.Len(t, attReaders, 0)
|
||||
}
|
||||
|
||||
func TestParseTextPlainLatin2Subject(t *testing.T) {
|
||||
f := getFileReader("text_plain_latin2_subject.eml")
|
||||
|
||||
m, _, plainBody, attReaders, err := Parse(f, "", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, `"Sender" <sender@pm.me>`, m.Sender.String())
|
||||
assert.Equal(t, `"Receiver" <receiver@pm.me>`, m.ToList[0].String())
|
||||
assert.Equal(t, `If you can read this you understand the example.`, m.Subject)
|
||||
|
||||
assert.Equal(t, "body", m.Body)
|
||||
assert.Equal(t, "body", plainBody)
|
||||
|
||||
assert.Len(t, attReaders, 0)
|
||||
}
|
||||
|
||||
func TestParseTextPlainUnknownCharsetIsActuallyLatin1(t *testing.T) {
|
||||
f := getFileReader("text_plain_unknown_latin1.eml")
|
||||
|
||||
|
||||
6
pkg/message/testdata/text_plain_latin2_subject.eml
vendored
Normal file
6
pkg/message/testdata/text_plain_latin2_subject.eml
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
From: Sender <sender@pm.me>
|
||||
To: Receiver <receiver@pm.me>
|
||||
Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
|
||||
=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=
|
||||
|
||||
body
|
||||
5
pkg/message/testdata/text_plain_utf8_subject.eml
vendored
Normal file
5
pkg/message/testdata/text_plain_utf8_subject.eml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
From: Sender <sender@pm.me>
|
||||
To: Receiver <receiver@pm.me>
|
||||
Subject: =?UTF-8?B?5rGJ5a2X5rGJ5a2X5rGJ?=
|
||||
|
||||
body
|
||||
Reference in New Issue
Block a user