From 6bfef982cbe6ca2209bebeb92a0a14a77c36f194 Mon Sep 17 00:00:00 2001 From: Toshio Maki Date: Wed, 6 Sep 2017 16:51:49 +0900 Subject: [PATCH] Fix that Message#attachments cannot count singlepart attachment --- CHANGELOG.rdoc | 1 + lib/mail/attachments_list.rb | 8 +++++--- lib/mail/message.rb | 20 +++++++++++++++++++- lib/mail/parts_list.rb | 4 ++-- spec/mail/attachments_list_spec.rb | 10 ++++++++++ 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 0e40b1396..3b175f722 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -58,6 +58,7 @@ Bugs: * #1110 - Fix that Mail::Multibyte::Chars#initialize mutated its argument by calling force_encoding on it. (jeremy) * #1113 - Eliminate attachment corruption caused by CRLF conversion. (jeremy) * #1131 - Fix that Message#without_attachments! didn't parse the remaining parts. (jeremy) +* #1143 - Fix that Message#attachments cannot count singlepart attachment. (kirikak2) == Version 2.6.4 - Wed Mar 23 08:16 -0700 2016 Jeremy Daer diff --git a/lib/mail/attachments_list.rb b/lib/mail/attachments_list.rb index ca7d0d6ae..9a4895acd 100644 --- a/lib/mail/attachments_list.rb +++ b/lib/mail/attachments_list.rb @@ -2,11 +2,13 @@ module Mail class AttachmentsList < Array - def initialize(parts_list) + def initialize(parts_list, body_attachment = nil) @parts_list = parts_list @content_disposition_type = 'attachment' - parts_list.map { |p| - if p.mime_type == 'message/rfc822' + [body_attachment].concat(parts_list).map { |p| + if p.nil? + nil + elsif p.mime_type == 'message/rfc822' Mail.new(p.body.encoded).attachments elsif p.parts.empty? p if p.attachment? diff --git a/lib/mail/message.rb b/lib/mail/message.rb index e163041d5..629f8d2e7 100644 --- a/lib/mail/message.rb +++ b/lib/mail/message.rb @@ -1655,7 +1655,11 @@ def parts # mail.attachments[0] #=> Mail::Part (first attachment) # def attachments - parts.attachments + if !multipart? && attachment? && !self.instance_of?(Mail::Part) + parts.attachments(generate_attachment_part_from_body) + else + parts.attachments + end end def has_attachments? @@ -2167,5 +2171,19 @@ def do_delivery def decode_body_as_text Encodings.transcode_charset decode_body, charset, 'UTF-8' end + + def generate_attachment_part_from_body + part = Mail::Part.new(nil) + header_part = [] + header_part << header[:content_type].encoded if header[:content_type] + header_part << header[:content_disposition].encoded if header[:content_disposition] + header_part << header[:content_transfer_encoding].encoded if header[:content_transfer_encoding] + header_part << header[:content_discription].encoded if header[:content_discription] + part.header = header_part.join + unless @body.nil? + part.body = @body.encoded + end + part + end end end diff --git a/lib/mail/parts_list.rb b/lib/mail/parts_list.rb index e64669734..c3d9ad2f3 100644 --- a/lib/mail/parts_list.rb +++ b/lib/mail/parts_list.rb @@ -21,8 +21,8 @@ def to_yaml(options = {}) # :nodoc: @parts.to_yaml(options) end - def attachments - Mail::AttachmentsList.new(@parts) + def attachments(body_attachment = nil) + Mail::AttachmentsList.new(@parts, body_attachment) end def collect diff --git a/spec/mail/attachments_list_spec.rb b/spec/mail/attachments_list_spec.rb index bff14e1fe..0845bc24b 100644 --- a/spec/mail/attachments_list_spec.rb +++ b/spec/mail/attachments_list_spec.rb @@ -128,6 +128,16 @@ def check_decoded(actual, expected) end + describe "single attachment" do + subject{ read_fixture("emails", "attachment_emails", "attachment_only_email.eml") } + + it "should get one attachment from #attachments method" do + expect(subject.attachments.length).to eq(1) + expect(subject.attachments[0].filename).to eq("blah.gz") + expect(subject.attachments[0].decoded).not_to be_nil + end + end + describe "multiple attachments" do it "should allow you to pass in more than one attachment" do