From f58ab2283d745449ca2c0634350eeb95c7f182d0 Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Wed, 6 Oct 2021 15:07:29 +0300 Subject: [PATCH] FIX: Parse address lists in embedded emails (#14514) Same fix is applied to emails immediately after being parsed because long headers are sometimes in an invalid format. --- lib/email/receiver.rb | 28 +++++------------- lib/email/validator.rb | 28 ++++++++++++++++++ spec/components/email/receiver_spec.rb | 8 +++++ .../emails/long_embedded_email_headers.eml | Bin 0 -> 487 bytes 4 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 lib/email/validator.rb create mode 100644 spec/fixtures/emails/long_embedded_email_headers.eml diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index 207e418d70e..7c76c44d613 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -3,7 +3,6 @@ require "digest" module Email - class Receiver # If you add a new error, you need to # * add it to Email::Processor#handle_failure() @@ -72,8 +71,7 @@ module Email # do not create a new `IncomingEmail` record to avoid double ups. return if @incoming_email = find_existing_and_update_imap - ensure_valid_address_lists - ensure_valid_date + Email::Validator.ensure_valid!(@mail) @from_email, @from_display_name = parse_from_field @from_user = User.find_by_email(@from_email) @@ -121,22 +119,6 @@ module Email incoming_email end - def ensure_valid_address_lists - [:to, :cc, :bcc].each do |field| - addresses = @mail[field] - - if addresses&.errors.present? - @mail[field] = addresses.to_s.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i) - end - end - end - - def ensure_valid_date - if @mail.date.nil? - raise InvalidPost, I18n.t("system_messages.email_reject_invalid_post_specified.date_invalid") - end - end - def is_blocked? return false if SiteSetting.ignore_by_title.blank? Regexp.new(SiteSetting.ignore_by_title, Regexp::IGNORECASE) =~ @mail.subject @@ -915,7 +897,13 @@ module Email end def embedded_email - @embedded_email ||= embedded_email_raw.present? ? Mail.new(embedded_email_raw) : nil + @embedded_email ||= if embedded_email_raw.present? + mail = Mail.new(embedded_email_raw) + Email::Validator.ensure_valid_address_lists!(mail) + mail + else + nil + end end def process_forwarded_email(destination, user) diff --git a/lib/email/validator.rb b/lib/email/validator.rb new file mode 100644 index 00000000000..2795055a93e --- /dev/null +++ b/lib/email/validator.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Email + class Validator + def self.ensure_valid!(mail) + Email::Validator.ensure_valid_address_lists!(mail) + Email::Validator.ensure_valid_date!(mail) + + mail + end + + def self.ensure_valid_address_lists!(mail) + [:to, :cc, :bcc].each do |field| + addresses = mail[field] + + if addresses&.errors.present? + mail[field] = addresses.to_s.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i) + end + end + end + + def self.ensure_valid_date!(mail) + if mail.date.nil? + raise Email::Receiver::InvalidPost, I18n.t("system_messages.email_reject_invalid_post_specified.date_invalid") + end + end + end +end diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb index 0f73e889623..a7bbd40650a 100644 --- a/spec/components/email/receiver_spec.rb +++ b/spec/components/email/receiver_spec.rb @@ -2024,4 +2024,12 @@ describe Email::Receiver do expect { receive(email_3) }.to change { Topic.count }.by(0).and change { Post.where(post_type: Post.types[:regular]).count }.by(1) end end + + it 'fixes valid addresses in embedded emails' do + Fabricate(:group, incoming_email: "group-fwd@example.com") + process(:long_embedded_email_headers) + incoming_email = IncomingEmail.find_by(message_id: "example1@mail.gmail.com") + expect(incoming_email.cc_addresses).to include("a@example.com") + expect(incoming_email.cc_addresses).to include("c@example.com") + end end diff --git a/spec/fixtures/emails/long_embedded_email_headers.eml b/spec/fixtures/emails/long_embedded_email_headers.eml new file mode 100644 index 0000000000000000000000000000000000000000..0442698e92c8eee74c811dffe31379324b10b7a4 GIT binary patch literal 487 zcmbV|Piuof5XJBFDPHd?y8UxlmS7XL%|Uud+WTgADhb*Rt71QXt0^H;N}zL?f%lll z{H9!&dHBY@-MbHoB#J519ZPI<7eL^}bP%yfAQE{myJ>?IMSc6XbRXmiAfIM z2YYGJ%1ErB%%!*pkU`m$W*J1`xllMiXm8n~IT7IO{U2QX4gQPywPg?0fA`ttG?HHb c$4LDMrDwYVmQb{tX+-qQb?q=XU)vk{0tCO9B>(^b literal 0 HcmV?d00001