diff --git a/Manifest.txt b/Manifest.txt index 99826ef4..f09cdcb3 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -127,6 +127,7 @@ test/fixtures/bad-content-transfer-encoding-1.eml test/fixtures/binary-content-transfer-encoding-2.eml test/fixtures/blank-header-fields.eml test/fixtures/contacts.txt +test/fixtures/embedded-message-rfc6532.eml test/fixtures/embedded-message.eml test/fixtures/invalid-date.eml test/fixtures/mailing-list-header.eml diff --git a/lib/sup/message.rb b/lib/sup/message.rb index 3354507c..fb92c584 100644 --- a/lib/sup/message.rb +++ b/lib/sup/message.rb @@ -460,6 +460,11 @@ def multipart_encrypted_to_chunks m end end + def has_embedded_message? m + return false unless m.header.content_type + %w(message/rfc822 message/global).include? m.header.content_type.downcase + end + ## takes a RMail::Message, breaks it into Chunk:: classes. def message_to_chunks m, encrypted=false, sibling_types=[] if m.multipart? @@ -477,7 +482,7 @@ def message_to_chunks m, encrypted=false, sibling_types=[] end chunks - elsif m.header.content_type && m.header.content_type.downcase == "message/rfc822" + elsif has_embedded_message? m encoding = m.header["Content-Transfer-Encoding"] if m.body body = diff --git a/test/fixtures/embedded-message-rfc6532.eml b/test/fixtures/embedded-message-rfc6532.eml new file mode 100644 index 00000000..16341f80 --- /dev/null +++ b/test/fixtures/embedded-message-rfc6532.eml @@ -0,0 +1,33 @@ +Return-Path: +From: Sender +To: +Subject: Email with embedded message +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="----------=_4F506AC2.EE281DC4" +Message-Id: <9181f493-df49-4af5-8ad2-e1a8eb692a98> +Date: Wed, 15 Jul 2020 19:48:41 +0100 + +This is a multi-part message in MIME format. + +------------=_4F506AC2.EE281DC4 +Content-Type: text/plain; charset=iso-8859-1 +Content-Disposition: inline +Content-Transfer-Encoding: 8bit + +Example outer message. + + +------------=_4F506AC2.EE281DC4 +Content-Type: message/global +Content-Transfer-Encoding: 8bit + +From: "Embed sender" +To: +Subject: Embedded subject line with emoji ✨ +X-heävy-mëtal-ümlaut: yes +Date: Sun, 12 May 2024 17:34:29 +1000 + +Example embedded message, with UTF-8 headers. + +------------=_4F506AC2.EE281DC4-- + diff --git a/test/test_message.rb b/test/test_message.rb index 3a8a1f48..8ee197e9 100644 --- a/test/test_message.rb +++ b/test/test_message.rb @@ -344,6 +344,35 @@ def test_embedded_message assert_equal("Second line.", chunks[2].lines[1]) end + def test_embedded_message_rfc6532 + source = DummySource.new("sup-test://test_embedded_message_rfc6532") + source.messages = [ fixture_path("embedded-message-rfc6532.eml") ] + + sup_message = Message.build_from_source(source, 0) + + chunks = sup_message.load_from_source! + assert_equal(3, chunks.length) + + assert_equal("Email with embedded message", sup_message.subj) + + assert(chunks[0].is_a? Redwood::Chunk::Text) + assert_equal("Example outer message.", chunks[0].lines[0]) + + assert(chunks[1].is_a? Redwood::Chunk::EnclosedMessage) + assert_equal(4, chunks[1].lines.length) + assert_equal("From: Embed sender ", chunks[1].lines[0]) + assert_equal("To: rcpt2 ", chunks[1].lines[1]) + assert_equal("Date: ", chunks[1].lines[2][0..5]) + assert_equal( + Time.rfc2822("Sun, 12 May 2024 17:34:29 +1000"), + Time.rfc2822(chunks[1].lines[2][6..-1]) + ) + assert_equal("Subject: Embedded subject line with emoji ✨", chunks[1].lines[3]) + + assert(chunks[2].is_a? Redwood::Chunk::Text) + assert_equal("Example embedded message, with UTF-8 headers.", chunks[2].lines[0]) + end + def test_malicious_attachment_names source = DummySource.new("sup-test://test_blank_header_lines") source.messages = [ fixture_path('malicious-attachment-names.eml') ]