From f5f953b3ab15bcdf2ee8b8ba8f4f233a66ddc9d9 Mon Sep 17 00:00:00 2001
From: Mechiel Lukkien <mechiel@ueber.net>
Date: Mon, 14 Aug 2023 15:40:27 +0200
Subject: [PATCH] handle parsing message header without header/body separator

the commit before the previous added tests with a message with only 1 header
line. it's a valid message, but Go's mail.ReadMessage doesn't handle it with
go1.20 and earlier. the automated "test with previous go release" caught it.
work around it by adding the expected but absent \r\n to the parse function.
---
 message/part.go | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/message/part.go b/message/part.go
index ce0bb13..f193bc5 100644
--- a/message/part.go
+++ b/message/part.go
@@ -376,7 +376,18 @@ func parseHeader(r io.Reader) (textproto.MIMEHeader, error) {
 	// first handles email messages properly, while the second only works for HTTP
 	// headers.
 	var zero textproto.MIMEHeader
-	msg, err := mail.ReadMessage(bufio.NewReader(r))
+
+	// We read the header and add the optional \r\n header/body separator. If the \r\n
+	// is missing, parsing with Go <1.21 results in an EOF error.
+	// todo: directly parse from reader r when Go 1.20 is no longer supported.
+	buf, err := io.ReadAll(r)
+	if err != nil {
+		return zero, err
+	}
+	if bytes.HasSuffix(buf, []byte("\r\n")) && !bytes.HasSuffix(buf, []byte("\r\n\r\n")) {
+		buf = append(buf, "\r\n"...)
+	}
+	msg, err := mail.ReadMessage(bytes.NewReader(buf))
 	if err != nil {
 		return zero, err
 	}