Files
mailgoserver/internal/smtpserver/attachments_test.go
T

80 lines
2.3 KiB
Go

package smtpserver
import (
"strings"
"testing"
)
// TestParseMessageDecodesBase64Attachment guards against a bug where
// mime/multipart.Reader only auto-decodes quoted-printable (not base64), so a
// base64-encoded attachment part was stored/read back as raw base64 text instead of
// its actual decoded bytes.
func TestParseMessageDecodesBase64Attachment(t *testing.T) {
raw := "" +
"From: sender@example.com\r\n" +
"To: rcpt@example.com\r\n" +
"Subject: test\r\n" +
"MIME-Version: 1.0\r\n" +
"Content-Type: multipart/mixed; boundary=\"BOUND\"\r\n" +
"\r\n" +
"--BOUND\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"hello\r\n" +
"--BOUND\r\n" +
"Content-Type: application/octet-stream\r\n" +
"Content-Disposition: attachment; filename=\"LICENSE\"\r\n" +
"Content-Transfer-Encoding: BASE64\r\n" +
"\r\n" +
"SGVsbG8sIHdvcmxkIQ==\r\n" +
"--BOUND--\r\n"
parsed, err := parseMessage([]byte(raw))
if err != nil {
t.Fatalf("parseMessage: %v", err)
}
if len(parsed.Attachments) != 1 {
t.Fatalf("got %d attachments, want 1", len(parsed.Attachments))
}
got := string(parsed.Attachments[0].Data)
want := "Hello, world!"
if got != want {
t.Errorf("attachment data = %q, want %q (decoded from base64, not left as raw base64 text)", got, want)
}
}
// TestParseMessageLeavesNonBase64EncodingsAlone confirms 7bit/8bit/absent
// Content-Transfer-Encoding parts pass through unmodified.
func TestParseMessageLeavesNonBase64EncodingsAlone(t *testing.T) {
raw := "" +
"From: sender@example.com\r\n" +
"To: rcpt@example.com\r\n" +
"Subject: test\r\n" +
"MIME-Version: 1.0\r\n" +
"Content-Type: multipart/mixed; boundary=\"BOUND\"\r\n" +
"\r\n" +
"--BOUND\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"hello\r\n" +
"--BOUND\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Disposition: attachment; filename=\"notes.txt\"\r\n" +
"Content-Transfer-Encoding: 7bit\r\n" +
"\r\n" +
"plain text content\r\n" +
"--BOUND--\r\n"
parsed, err := parseMessage([]byte(raw))
if err != nil {
t.Fatalf("parseMessage: %v", err)
}
if len(parsed.Attachments) != 1 {
t.Fatalf("got %d attachments, want 1", len(parsed.Attachments))
}
got := strings.TrimSpace(string(parsed.Attachments[0].Data))
if got != "plain text content" {
t.Errorf("attachment data = %q, want %q", got, "plain text content")
}
}