FIX: Correct corrupt encoding in emails containing attachments

FIX: Correct corrupt encoding in emails containing attachments

diff --git a/lib/email/sender.rb b/lib/email/sender.rb
index f5b3c4b..027d858 100644
--- a/lib/email/sender.rb
+++ b/lib/email/sender.rb
@@ -332,8 +332,11 @@ module Email
         content = Mail::Part.new do
           content_type "multipart/alternative"
 
-          part html_part
-          part text_part
+          # we have to re-specify the charset and give the part the decoded body
+          # here otherwise the parts will get encoded with US-ASCII which makes
+          # a bunch of characters not render correctly in the email
+          part content_type: "text/html; charset=utf-8", body: html_part.body.decoded
+          part content_type: "text/plain; charset=utf-8", body: text_part.body.decoded
         end
 
         @message.parts.unshift(content)
diff --git a/spec/components/email/sender_spec.rb b/spec/components/email/sender_spec.rb
index 54b30ce..d3c7741 100644
--- a/spec/components/email/sender_spec.rb
+++ b/spec/components/email/sender_spec.rb
@@ -378,7 +378,7 @@ describe Email::Sender do
     fab!(:post) { Fabricate(:post) }
     fab!(:reply) do
       raw = <<~RAW
-        Hello world!
+        Hello world! It’s a great day!
         #{UploadMarkdown.new(small_pdf).attachment_markdown}
         #{UploadMarkdown.new(large_pdf).attachment_markdown}
         #{UploadMarkdown.new(image).image_markdown}
@@ -460,6 +460,13 @@ describe Email::Sender do
           expect(message.html_part.body).to include("embedded-secure-image")
           expect(message.attachments.length).to eq(4)
         end
+
+        it "uses correct UTF-8 encoding for the body of the email" do
+          Email::Sender.new(message, :valid_type).send
+          expect(message.html_part.body).not_to include("Itâ\u0080\u0099s")
+          expect(message.html_part.body).to include("It’s")
+          expect(message.html_part.charset.downcase).to eq("utf-8")
+        end
       end
     end
 
@@ -491,6 +498,13 @@ describe Email::Sender do
       expect(message.parts[0].content_type).to start_with("multipart/alternative")
       expect(message.parts[0].parts.size).to eq(2)
     end
+
+    it "uses correct UTF-8 encoding for the body of the email" do
+      Email::Sender.new(message, :valid_type).send
+      expect(message.html_part.body).not_to include("Itâ\u0080\u0099s")
+      expect(message.html_part.body).to include("It’s")
+      expect(message.html_part.charset.downcase).to eq("utf-8")
+    end
   end
 
   context 'with a deleted post' do

GitHub sha: a8ed0b46

1 Like

This commit appears in #10770 which was approved by pmusaraj and SamSaffron. It was merged by SamSaffron.