sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 15f066bd05042ed732a239046efe368834c48c1f
parent bb204e66679cc52eb92b1d6a5bcd3dc6fccf8417
Author: Iain Parris <ipv2.vcs@parris.org>
Date:   Tue, 20 Oct 2020 00:42:38 +0100

fix #585: invalid charset for text attachment

When a text/plain attachment has an invalid charset, then default to
US-ASCII. Fixes crash in #585 (ArgumentError "unknown encoding name").

Diffstat:
M lib/sup/message_chunks.rb | 7 ++++++-
M test/fixtures/text-attachments-with-charset.eml | 9 ++++++++-
M test/test_message.rb | 6 +++++-
3 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/lib/sup/message_chunks.rb b/lib/sup/message_chunks.rb
@@ -128,7 +128,12 @@ EOS
 
       text = case @content_type
       when /^text\/plain\b/
-        @raw_content.force_encoding(encoded_content.charset || 'US-ASCII')
+        begin
+          charset = Encoding.find(encoded_content.charset || 'US-ASCII')
+        rescue ArgumentError
+          charset = 'US-ASCII'
+        end
+        @raw_content.force_encoding(charset)
       else
         HookManager.run "mime-decode", :content_type => @content_type,
                         :filename => lambda { write_to_disk },
diff --git a/test/fixtures/text-attachments-with-charset.eml b/test/fixtures/text-attachments-with-charset.eml
@@ -42,5 +42,12 @@ Content-Disposition: attachment; filename="bad.txt"
 MIME-Version: 1.0
 
 Embedded=F0garbage
---===============2385509127900810307==--
+
+--===============2385509127900810307==
+Content-Type: text/plain; charset="invalid-test"; name="invalid-charset.txt"
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: attachment; filename="invalid-charset.txt"
+
+Example invalid charset
+--===============2385509127900810307==
 
diff --git a/test/test_message.rb b/test/test_message.rb
@@ -180,7 +180,7 @@ class TestMessage < Minitest::Test
     sup_message.load_from_source!
 
     chunks = sup_message.load_from_source!
-    assert_equal(5, chunks.length)
+    assert_equal(6, chunks.length)
     assert(chunks[0].is_a? Redwood::Chunk::Text)
     ## The first attachment declares charset=us-ascii
     assert(chunks[1].is_a? Redwood::Chunk::Attachment)
@@ -195,6 +195,10 @@ class TestMessage < Minitest::Test
     ## which will be replaced with U+FFFD REPLACEMENT CHARACTER
     assert(chunks[4].is_a? Redwood::Chunk::Attachment)
     assert_equal(["Embedded\ufffdgarbage"], chunks[4].lines)
+    ## The fifth attachment has an invalid charset, which should still
+    ## be handled gracefully
+    assert(chunks[5].is_a? Redwood::Chunk::Attachment)
+    assert_equal(["Example invalid charset"], chunks[5].lines)
   end
 
   def test_mailing_list_header