Fixes issue #2894 - Emails with binary body (attachment as body) get handled as if they were text messages which breaks the attachment.
This commit is contained in:
parent
264853dcbe
commit
6692869dd8
3 changed files with 84 additions and 27 deletions
|
@ -574,13 +574,27 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
|||
def collect_attachments(mail)
|
||||
attachments = []
|
||||
|
||||
# Add non-plaintext body as an attachment
|
||||
if mail.html_part&.body.present? ||
|
||||
(!mail.multipart? && mail.mime_type.present? && mail.mime_type != 'text/plain')
|
||||
attachments.push(*get_nonplaintext_body_as_attachment(mail))
|
||||
|
||||
mail.parts.each do |part|
|
||||
attachments.push(*gracefully_get_attachments(part, attachments, mail))
|
||||
end
|
||||
|
||||
attachments
|
||||
end
|
||||
|
||||
def get_nonplaintext_body_as_attachment(mail)
|
||||
if !(mail.html_part&.body.present? || (!mail.multipart? && mail.mime_type.present? && mail.mime_type != 'text/plain'))
|
||||
return
|
||||
end
|
||||
|
||||
message = mail.html_part || mail
|
||||
|
||||
filename = message.filename.presence ||
|
||||
(message.mime_type.eql?('text/html') ? 'message.html' : '-no name-')
|
||||
if !mail.mime_type.starts_with?('text/') && mail.html_part.blank?
|
||||
return gracefully_get_attachments(message, [], mail)
|
||||
end
|
||||
|
||||
filename = message.filename.presence || (message.mime_type.eql?('text/html') ? 'message.html' : '-no name-')
|
||||
|
||||
headers_store = {
|
||||
'content-alternative' => true,
|
||||
|
@ -589,23 +603,19 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
|
|||
'Charset' => message.charset,
|
||||
}.reject { |_, v| v.blank? }
|
||||
|
||||
attachments.push({ data: body_text(message),
|
||||
[{
|
||||
data: body_text(message),
|
||||
filename: filename,
|
||||
preferences: headers_store })
|
||||
preferences: headers_store
|
||||
}]
|
||||
end
|
||||
|
||||
mail.parts.each do |part|
|
||||
|
||||
new_attachments = get_attachments(part, attachments, mail).flatten.compact
|
||||
attachments.push(*new_attachments)
|
||||
def gracefully_get_attachments(part, attachments, mail)
|
||||
get_attachments(part, attachments, mail).flatten.compact
|
||||
rescue => e # Protect process to work with spam emails (see test/fixtures/mail15.box)
|
||||
raise e if (fail_count ||= 0).positive?
|
||||
|
||||
(fail_count += 1) && retry
|
||||
|
||||
end
|
||||
|
||||
attachments
|
||||
end
|
||||
|
||||
def get_attachments(file, attachments, mail)
|
||||
|
|
20
test/data/mail/mail086.box
Normal file
20
test/data/mail/mail086.box
Normal file
File diff suppressed because one or more lines are too long
27
test/data/mail/mail086.yml
Normal file
27
test/data/mail/mail086.yml
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue