Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ Compatibility:
Features:
* Message#inspect_structure and PartsList#inspect_structure pretty-print the hierarchy of message parts. (TylerRick)

Bugs:
* Handle case when inline image attachment parts do not contain a filename or Content-Location header. (lao9)

Please check [2-7-stable](https://github.com/mikel/mail/blob/2-7-stable/CHANGELOG.rdoc) for previous changes.
14 changes: 11 additions & 3 deletions lib/mail/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ def decode_body
# Returns true if this part is an attachment,
# false otherwise.
def attachment?
!!find_attachment
!!find_attachment_name || inline_image?
end

# Returns the attachment data if there is any
Expand All @@ -1921,7 +1921,7 @@ def attachment

# Returns the filename of the attachment
def filename
find_attachment
find_attachment_name
end

def all_parts
Expand Down Expand Up @@ -2117,7 +2117,7 @@ def init_with_string(string)
end

# Returns the filename of the attachment (if it exists) or returns nil
def find_attachment
def find_attachment_name
content_type_name = header[:content_type].filename rescue nil
content_disp_name = header[:content_disposition].filename rescue nil
content_loc_name = header[:content_location].location rescue nil
Expand All @@ -2135,6 +2135,14 @@ def find_attachment
filename
end

def inline_image?
image? && inline?
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline? is a method on the Mail::Part subclass, so this'll break for a Mail::Message itself.

Could move this into Mail::Part and override the attachment? method, perhaps?

# class Part < Message

def attachment?
  super || inline_image?
end

# …

def inline_image?
  # …

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback - I'll try to get this in next by next week!


def image?
header[:content_type] && header[:content_type].main_type == "image"
end

def do_delivery
begin
if perform_deliveries
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Mime-Version: 1.0 (Apple Message framework v730)
Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151
Message-Id: <[email protected]>
From: [email protected]
Subject: testing
Date: Mon, 6 Jun 2005 22:21:22 +0200
To: [email protected]


--Apple-Mail-13-196941151
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=ISO-8859-1;
delsp=yes;
format=flowed

This is the first part.

--Apple-Mail-13-196941151
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-ID: <qbFGyPQAS8>
Content-Disposition: inline

jamisSqGSIb3DQEHAqCAMIjamisxCzAJBgUrDgMCGgUAMIAGCSqGSjamisEHAQAAoIIFSjCCBUYw
ggQujamisQICBD++ukQwDQYJKojamisNAQEFBQAwMTELMAkGA1UEBhMCRjamisAKBgNVBAoTA1RE
QzEUMBIGjamisxMLVERDIE9DRVMgQ0jamisNMDQwMjI5MTE1OTAxWhcNMDYwMjamisIyOTAxWjCB
gDELMAkGA1UEjamisEsxKTAnBgNVBAoTIEjamisuIG9yZ2FuaXNhdG9yaXNrIHRpbjamisRuaW5=

--Apple-Mail-13-196941151--
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Mime-Version: 1.0 (Apple Message framework v730)
Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151
Message-Id: <[email protected]>
From: [email protected]
Subject: testing
Date: Mon, 6 Jun 2005 22:21:22 +0200
To: [email protected]


--Apple-Mail-13-196941151
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=ISO-8859-1;
delsp=yes;
format=flowed

This is the first part.

--Apple-Mail-13-196941151
Content-Type: image/jpeg; filename="Photo25.jpg"
Content-Transfer-Encoding: base64
Content-ID: <qbFGyPQAS8>
Content-Disposition: inline

jamisSqGSIb3DQEHAqCAMIjamisxCzAJBgUrDgMCGgUAMIAGCSqGSjamisEHAQAAoIIFSjCCBUYw
ggQujamisQICBD++ukQwDQYJKojamisNAQEFBQAwMTELMAkGA1UEBhMCRjamisAKBgNVBAoTA1RE
QzEUMBIGjamisxMLVERDIE9DRVMgQ0jamisNMDQwMjI5MTE1OTAxWhcNMDYwMjamisIyOTAxWjCB
gDELMAkGA1UEjamisEsxKTAnBgNVBAoTIEjamisuIG9yZ2FuaXNhdG9yaXNrIHRpbjamisRuaW5=

--Apple-Mail-13-196941151--
5 changes: 5 additions & 0 deletions spec/mail/attachments_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ def check_decoded(actual, expected)
expect(mail.attachments[0].filename).to eq 'api.rb'
end

it "should not need filename for inline attachments" do
mail = read_fixture('emails/attachment_emails/attachment_missing_filename.eml')
expect(mail.attachments.length).to eq 1
end

it "should decode an attachment" do
mail = read_fixture('emails/attachment_emails/attachment_pdf.eml')
expect(mail.attachments[0].decoded.length).to eq 1026
Expand Down
45 changes: 40 additions & 5 deletions spec/mail/message_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,7 @@ def message_headers_should_match(message, other)
part.body = 'a' * 999
end
mail.encoded

expect(mail.parts.count).to eq(1)
expect(mail.parts.last.content_transfer_encoding).to match(/7bit|8bit|binary/)
end
Expand All @@ -1459,19 +1459,19 @@ def message_headers_should_match(message, other)
end
end
end

it "should not add an empty charset header" do
@mail.charset = nil

expect(@mail.multipart?).to eq true
expect(@mail.parts.count).to eq 2
expect(@mail.encoded.scan(/charset=UTF-8/).count).to eq 2
end

it "should remove the charset header" do
@mail.charset = 'iso-8859-1'
@mail.charset = nil

expect(@mail.encoded.scan(/charset=UTF-8/).count).to eq 2
expect(@mail.encoded.scan(/charset=iso-8859-1/).count).to eq 0
end
Expand All @@ -1495,6 +1495,41 @@ def message_headers_should_match(message, other)
end
end

describe "attachment?" do
context "with content location" do
subject do
read_fixture('emails', 'attachment_emails', 'attachment_content_location.eml')
end

it "returns true using the content location filename" do
expect(subject.parts[0].attachment?).to eq(false)
expect(subject.parts[1].attachment?).to eq(true)
end
end

context "with content type filename" do
subject do
read_fixture('emails', 'attachment_emails', 'attachment_with_filename.eml')
end

it "returns true using the content type filename" do
expect(subject.parts[0].attachment?).to eq(false)
expect(subject.parts[1].attachment?).to eq(true)
end
end

context "without content location or filename" do
subject do
read_fixture('emails', 'attachment_emails', 'attachment_missing_filename.eml')
end

it "returns true for the inline attachment" do
expect(subject.parts[0].attachment?).to eq(false)
expect(subject.parts[1].attachment?).to eq(true)
end
end
end

describe "content-transfer-encoding" do

it "should use 7bit for only US-ASCII chars" do
Expand Down