Skip to content

Commit 30271cf

Browse files
committed
Don't split Quoted Printable characters during folding procedure
1 parent f7e2be8 commit 30271cf

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

header.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package message
33
import (
44
"mime"
55
"net/textproto"
6+
"regexp"
67
"strings"
78

89
"github.com/emersion/go-message/charset"
@@ -40,6 +41,8 @@ func formatHeaderField(k, v string) string {
4041
return s + "\r\n"
4142
}
4243

44+
qpReg := regexp.MustCompile("(=[0-9A-Z]{2,2})+")
45+
4346
first := true
4447
for len(v) > 0 {
4548
maxlen := maxHeaderLen
@@ -59,8 +62,20 @@ func formatHeaderField(k, v string) string {
5962
folding = "\r\n"
6063
}
6164
} else {
65+
// Find the last QP character before limit
66+
foldAtQP := qpReg.FindAllStringIndex(v[:foldBefore], -1)
6267
// Find the closest whitespace before i
63-
foldAt = strings.LastIndexAny(v[:foldBefore], " \t\n")
68+
foldAtEOL := strings.LastIndexAny(v[:foldBefore], " \t\n")
69+
70+
foldAt = foldAtEOL
71+
72+
if len(foldAtQP) > 0 {
73+
foldAtQPLastIndex := foldAtQP[len(foldAtQP)-1][0]
74+
if foldAtQPLastIndex > foldAt {
75+
foldAt = foldAtQPLastIndex
76+
}
77+
}
78+
6479
if foldAt == 0 {
6580
// The whitespace we found was the previous folding WSP
6681
foldAt = foldBefore - 1

header_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,21 @@ var formatHeaderFieldTests = []struct {
5959
v: "This is yet \t another subject \t with many whitespace characters",
6060
formatted: "Subject: This is yet \t another subject \t \r\n with many whitespace characters\r\n",
6161
},
62+
{
63+
k: "Subject",
64+
v: "=?utf-8?q?=E2=80=9CDeveloper_reads_customer_requested_change.=E2=80=9D=0A?= =?utf-8?q?=0ACaravaggio=0A=0AOil_on...?=",
65+
formatted: "Subject: =?utf-8?q?=E2=80=9CDeveloper_reads_customer_requested_change.\r\n =E2=80=9D=0A?= =?utf-8?q?=0ACaravaggio=0A=0AOil_on...?=\r\n",
66+
},
67+
{
68+
k: "Subject",
69+
v: "=?utf-8?q?=E2=80=9CShort subject=E2=80=9D=0A?= =?utf-8?q?=0AAuthor=0A=0AOil_on...?=",
70+
formatted: "Subject: =?utf-8?q?=E2=80=9CShort subject=E2=80=9D=0A?= =?utf-8?q?\r\n =0AAuthor=0A=0AOil_on...?=\r\n",
71+
},
72+
{
73+
k: "Subject",
74+
v: "=?utf-8?q?=E2=80=9CVery long subject very long subject very long subject very long subject=E2=80=9D=0A?= =?utf-8?q?=0ALong second part of subject long second part of subject long second part of subject long subject=0A=0AOil_on...?=",
75+
formatted: "Subject: =?utf-8?q?=E2=80=9CVery long subject very long subject very long\r\n subject very long subject=E2=80=9D=0A?= =?utf-8?q?=0ALong second part of\r\n subject long second part of subject long second part of subject long\r\n subject=0A=0AOil_on...?=\r\n",
76+
},
6277
{
6378
k: "DKIM-Signature",
6479
v: "v=1;\r\n h=From:To:Reply-To:Subject:Message-ID:References:In-Reply-To:MIME-Version;\r\n d=example.org\r\n",

0 commit comments

Comments
 (0)