write base64 message parts with 76 data bytes on a line instead of 78

As required by RFC 2045 (MIME). The 78 byte lines work in practice, except that
SpamAssassin has rules that give messages with 78-byte lines spam points.

Mentioned by kjetilho on irc.
This commit is contained in:
Mechiel Lukkien
2025-04-03 10:22:15 +02:00
parent 00c8db98e6
commit 69d2699961
9 changed files with 16 additions and 13 deletions

View File

@ -27,7 +27,7 @@ func (w *HeaderWriter) Add(separator string, texts ...string) {
}
for _, text := range texts {
n := len(text)
if w.nonfirst && w.lineLen > 1 && w.lineLen+len(separator)+n > 78 {
if w.nonfirst && w.lineLen > 1 && w.lineLen+len(separator)+n > 76 {
w.b.WriteString("\r\n\t")
w.lineLen = 1
} else if w.nonfirst && separator != "" {
@ -45,7 +45,7 @@ func (w *HeaderWriter) Add(separator string, texts ...string) {
func (w *HeaderWriter) AddWrap(buf []byte, text bool) {
for len(buf) > 0 {
line := buf
n := 78 - w.lineLen
n := 76 - w.lineLen
if len(buf) > n {
if text {
if i := bytes.LastIndexAny(buf[:n], " \t"); i > 0 {

View File

@ -11,7 +11,9 @@ import (
func NeedsQuotedPrintable(text string) bool {
// ../rfc/2045:1025
for _, line := range strings.Split(text, "\r\n") {
if len(line) > 78 || strings.Contains(line, "\r") || strings.Contains(line, "\n") {
// 78 should be fine too, qp itself has a requirement of 76 bytes on a line, but
// using qp for anything longer than 76 is safer.
if len(line) > 76 || strings.Contains(line, "\r") || strings.Contains(line, "\n") {
return true
}
}