commit ac12be507b1473e12004f552bf34e8b4d8209532
parent f3b63120aa7c7610cf691f31e5998988ff813586
Author: Dan Callaghan <djc@djc.id.au>
Date: Sun, 7 Jul 2024 22:21:57 +1000
encode attachments if they have lines longer than 998 chars
As per:
https://datatracker.ietf.org/doc/html/rfc5322#section-2.1.1
Fixes #489.
Diffstat:
3 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/Manifest.txt b/Manifest.txt
@@ -169,6 +169,7 @@ test/unit/test_edit_message_mode.rb
test/unit/test_horizontal_selector.rb
test/unit/test_locale_fiddler.rb
test/unit/test_person.rb
+test/unit/test_rmail_message.rb
test/unit/util/test_query.rb
test/unit/util/test_string.rb
test/unit/util/test_uri.rb
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
@@ -80,7 +80,14 @@ module RMail
def self.make_file_attachment fn
bfn = File.basename fn
t = MIME::Types.type_for(bfn).first || MIME::Types.type_for("exe").first
- make_attachment IO.read(fn), t.content_type, t.encoding, bfn.to_s
+ payload = IO.read fn
+ ## Need to encode as base64 or quoted-printable if any lines are longer than 998 chars.
+ encoding = if t.encoding != t.default_encoding and payload.each_line.any? { |l| l.length > 998 }
+ t.default_encoding
+ else
+ t.encoding
+ end
+ make_attachment payload, t.content_type, encoding, bfn.to_s
end
def charset
diff --git a/test/unit/test_rmail_message.rb b/test/unit/test_rmail_message.rb
@@ -0,0 +1,36 @@
+require "test_helper"
+
+require "sup"
+
+class TestRMailMessage < Minitest::Test
+ def setup
+ @path = Dir.mktmpdir
+ end
+
+ def teardown
+ FileUtils.rm_r @path
+ end
+
+ def test_make_file_attachment
+ filename = File.join @path, "test.html"
+ File.write filename, "<html></html>"
+
+ a = RMail::Message.make_file_attachment(filename)
+ assert_equal "text/html; name=\"test.html\"", a.header["Content-Type"]
+ assert_equal "attachment; filename=\"test.html\"", a.header["Content-Disposition"]
+ assert_equal "8bit", a.header["Content-Transfer-Encoding"]
+ end
+
+ def test_make_file_attachment_text_with_long_lines
+ filename = File.join @path, "test.html"
+ File.write filename, "a" * 1023
+
+ a = RMail::Message.make_file_attachment(filename)
+ assert_equal "text/html; name=\"test.html\"", a.header["Content-Type"]
+ assert_equal "attachment; filename=\"test.html\"", a.header["Content-Disposition"]
+ assert_equal "quoted-printable", a.header["Content-Transfer-Encoding"]
+
+ qp_encoded = ("a" * 73 + "=\n") * 14 + "a=\n"
+ assert_equal qp_encoded, a.body
+ end
+end