package smtp2shoutrrr import ( "net/mail" "strings" "testing" "github.com/stretchr/testify/require" ) func readMessage(t *testing.T, raw string) *mail.Message { t.Helper() msg, err := mail.ReadMessage(strings.NewReader(raw)) require.NoError(t, err) return msg } // Regression: this header reached log.Fatalf, which exits the process. The // value is attacker-controlled and needs nothing but the ability to deliver a // message. func TestBodyRejectsMalformedContentType(t *testing.T) { for name, contentType := range map[string]string{ "parameter without a value": "text/plain; charset", "duplicate parameter": "text/plain; charset=utf-8; charset=ascii", "no media type": ";", "unterminated quoted value": `multipart/mixed; boundary="unterminated`, } { t.Run(name, func(t *testing.T) { email := ReceivedEmail{ Msg: readMessage(t, "Subject: Test\r\nContent-Type: "+contentType+"\r\n\r\nbody\r\n"), } body, err := email.Body() require.Error(t, err) require.ErrorIs(t, err, errMalformedMessage, "an unparseable header is permanent, so the sender must not be told to retry") require.Empty(t, body) }) } } func TestBodyReadsMessageWithoutContentType(t *testing.T) { email := ReceivedEmail{Msg: readMessage(t, "Subject: Test\r\n\r\nplain body\r\n")} body, err := email.Body() require.NoError(t, err) require.Equal(t, "plain body\r\n", body) } func TestBodyPrefersPlainTextPartOverHTML(t *testing.T) { email := ReceivedEmail{Msg: readMessage(t, strings.Join([]string{ "Subject: Test", `Content-Type: multipart/alternative; boundary="b"`, "", "--b", "Content-Type: text/html; charset=utf-8", "", "

html body

", "--b", "Content-Type: text/plain; charset=utf-8", "", "plain body", "--b--", "", }, "\r\n"))} body, err := email.Body() require.NoError(t, err) require.Equal(t, "plain body", body) } func TestBodyFallsBackToHTMLPart(t *testing.T) { email := ReceivedEmail{Msg: readMessage(t, strings.Join([]string{ "Subject: Test", `Content-Type: multipart/alternative; boundary="b"`, "", "--b", "Content-Type: text/html; charset=utf-8", "", "

html body

", "--b--", "", }, "\r\n"))} body, err := email.Body() require.NoError(t, err) require.Equal(t, "

html body

", body) }