FIX: Catch UndefinedConversionError for inbound emails (#13000)

Some emails coming in via the mail receiver can still end up
with bad encoding when trying to enqueue the job. This catches
the last encoding issue and forces iso-8559-1 and encodes to
UTF-8 to circumvent the issue.
This commit is contained in:
Martin Brennan
2021-05-10 14:26:23 +10:00
committed by GitHub
parent aaa034786a
commit c187ede3c6
3 changed files with 19 additions and 1 deletions

View File

@ -158,7 +158,7 @@ class Admin::EmailController < Admin::AdminController
begin begin
Jobs.enqueue(:process_email, mail: email_raw, retry_on_rate_limit: true, source: :handle_mail) Jobs.enqueue(:process_email, mail: email_raw, retry_on_rate_limit: true, source: :handle_mail)
rescue JSON::GeneratorError => e rescue JSON::GeneratorError, Encoding::UndefinedConversionError => e
if retry_count == 0 if retry_count == 0
email_raw = email_raw.force_encoding('iso-8859-1').encode("UTF-8") email_raw = email_raw.force_encoding('iso-8859-1').encode("UTF-8")
retry_count += 1 retry_count += 1

View File

@ -0,0 +1,12 @@
Return-Path: <discourse@bar.com>
From: Foo Bar <discourse@bar.com>
To: someone@else.com
CC: team@bar.com, wat@bar.com, reply+d400310beeae61d785c2ac6a2aacb210@bar.com
Subject: The more, the merrier
Date: Fri, 15 Jan 2016 00:12:43 +0100
Message-ID: <30@foo.bar.mail>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
It is more fun with more people. 𝗜 𝗮𝗺 𝗮 𝘀𝗶𝗻𝗴𝗹𝗲 person.

View File

@ -229,6 +229,12 @@ describe Admin::EmailController do
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.body).to eq("email has been received and is queued for processing") expect(response.body).to eq("email has been received and is queued for processing")
end end
it "retries enqueueing with forced UTF-8 encoding when encountering Encoding::UndefinedConversionError" do
post "/admin/email/handle_mail.json", params: { email_encoded: Base64.strict_encode64(email('encoding_undefined_conversion')) }
expect(response.status).to eq(200)
expect(response.body).to eq("email has been received and is queued for processing")
end
end end
describe '#rejected' do describe '#rejected' do