sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 6f0e4cfe53b62b5ea970c83cd4a562d247e8ada4
parent 9b4d42a2c864c61671d6aa6dc3b368e9b37466fe
Author: Dan Callaghan <djc@djc.id.au>
Date:   Mon, 18 Apr 2022 12:49:36 +1000

handle UTF-7 MIME parts also

Diffstat:
M lib/sup/message_chunks.rb | 14 +++++++++-----
M test/fixtures/text-attachments-with-charset.eml | 7 +++++++
M test/test_message.rb | 5 ++++-
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/lib/sup/message_chunks.rb b/lib/sup/message_chunks.rb
@@ -128,12 +128,16 @@ EOS
 
       text = case @content_type
       when /^text\/plain\b/
-        begin
-          charset = Encoding.find(encoded_content.charset || 'US-ASCII')
-        rescue ArgumentError
-          charset = 'US-ASCII'
+        if /^UTF-7$/i =~ encoded_content.charset
+          @raw_content.decode_utf7
+        else
+          begin
+            charset = Encoding.find(encoded_content.charset || 'US-ASCII')
+          rescue ArgumentError
+            charset = 'US-ASCII'
+          end
+          @raw_content.force_encoding(charset)
         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
@@ -50,4 +50,11 @@ Content-Disposition: attachment; filename="invalid-charset.txt"
 
 Example invalid charset
 --===============2385509127900810307==
+Content-Type: text/plain; charset="utf-7"
+Content-Transfer-Encoding: 7bit
+MIME-Version: 1.0
+Content-Disposition: attachment; filename="ascii.txt"
+
+This is +Jyg-UTF-7+Jyg-
+--===============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(6, chunks.length)
+    assert_equal(7, 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)
@@ -199,6 +199,9 @@ class TestMessage < Minitest::Test
     ## be handled gracefully
     assert(chunks[5].is_a? Redwood::Chunk::Attachment)
     assert_equal(["Example invalid charset"], chunks[5].lines)
+    ## The sixth attachment is UTF-7 encoded
+    assert(chunks[6].is_a? Redwood::Chunk::Attachment)
+    assert_equal(["This is ✨UTF-7✨"], chunks[6].lines)
   end
 
   def test_mailing_list_header