FIX: Parse address lists in embedded emails (#14514)

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.

diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb
index 207e418..7c76c44 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 0000000..2795055
--- /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 0f73e88..a7bbd40 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 0000000..0442698
--- /dev/null
+++ b/spec/fixtures/emails/long_embedded_email_headers.eml
@@ -0,0 +1,21 @@
+MIME-Version: 1.0
+Date: Sat, 2 Oct 2021 21:52:36 -0400
+Message-ID: <example1@mail.gmail.com>
+Subject: Fwd: Test Email
+From: Example Group <group@example.com>
+To: group-fwd@example.com
+Cc: C <c@example.com>, D <d@
+example.com>
+
+
+---------- Forwarded message ---------
+Date: Sat, 2 Oct 2021 21:52:36 -0400
+Message-ID: <example2@mail.gmail.com>
+Subject: Test Email
+From: User <user@example.com>
+To: Example Group <group@example.com>
+Cc: A <a@example.com>, B <
+b@example.com>
+
+
+Hello world!

GitHub sha: f58ab2283d745449ca2c0634350eeb95c7f182d0

This commit appears in #14514 which was approved by ZogStriP. It was merged by nbianca.