Skip to content

Commit

Permalink
Only use dot-stuff workaround on old Ruby versions (mikel#1372)
Browse files Browse the repository at this point in the history
* Dot stuff all lines, not only those containing a single period
* Only use dot-stuff workaround on old Ruby versions
  • Loading branch information
c960657 authored and jeremy committed Feb 20, 2020
1 parent 3393a28 commit c67129d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
== Version 2.7.2 (unreleased)

Bugs:
* Fix duplicate dots at beginning of lines. (c960657)


== Version 2.7.1 (2018-10-13)

Expand Down Expand Up @@ -870,5 +873,6 @@ content-disposition or content-location
* Added attachment.original_filename for ActionMailer friendliness

== Sat Oct 25 13:38:01 UTC 2009 Mikel Lindsaar <raasdnil@gmail.com>
=======

* Birthday, Mail released as a gem... phew
16 changes: 13 additions & 3 deletions lib/mail/network/delivery_methods/smtp_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,20 @@ def deliver!(mail)
end

private
# This is Net::SMTP's job, but before Ruby 2.x it does not dot-stuff
# an unterminated last line: https://bugs.ruby-lang.org/issues/9627
# Older versions of Net::SMTP does not dot-stuff an unterminated last line:
# https://bugs.ruby-lang.org/issues/9627
def dot_stuff?
RUBY_VERSION < "2.0.0" ||
RUBY_VERSION == "2.0.0" && RUBY_PATCHLEVEL < 576 ||
RUBY_VERSION >= "2.1.0" && RUBY_VERSION < "2.1.3"
end

def dot_stuff(message)
message.gsub(/(\r\n\.)(\r\n|$)/, '\1.\2')
if dot_stuff?
message.gsub(/(\r\n\.)([^\r\n]*$)/, '\1.\2')
else
message
end
end
end
end
49 changes: 48 additions & 1 deletion spec/mail/network/delivery_methods/smtp_connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,28 @@
Mail.delivery_method.smtp.finish
end

it "should not dot-stuff in recent Ruby versions" do
skip "is skipped on older Ruby versions" if RUBY_VERSION < '2.1.3'
expect(Mail.delivery_method.send(:dot_stuff?)).to eq false
end

it "dot-stuff unterminated last line of the message" do
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail.delivery_method.send(:dot_stuff?)

Mail.deliver do
from 'from@example.com'
to 'to@example.com'
subject 'dot-stuff last line'
body "this is a test\n... only a test\n... or is it?"
end

message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n... only a test\n.... or is it?")
end

it "dot-stuff unterminated last line of the message containing a single dot" do
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail.delivery_method.send(:dot_stuff?)

Mail.deliver do
from 'from@example.com'
to 'to@example.com'
Expand All @@ -24,7 +45,33 @@
end

message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n..\nonly a test\n..")
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test\n..")
end

it "should not dot-stuff unterminated last line with no leading dot" do
body = "this is a test\n.\nonly a test"

Mail.deliver do
from 'from@example.com'
to 'to@example.com'
subject 'dot-stuff last line'
body "this is a test\n.\nonly a test"
end

message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test")
end

it "should not dot-stuff newline-terminated last line" do
Mail.deliver do
from 'from@example.com'
to 'to@example.com'
subject 'dot-stuff last line'
body "this is a test\n.\nonly a test\n.\n"
end

message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test\n.\n")
end

it "should send an email using open SMTP connection" do
Expand Down
6 changes: 4 additions & 2 deletions spec/mail/network/delivery_methods/smtp_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@

describe "general usage" do
it "dot-stuff unterminated last line of the message" do
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail::SMTPConnection.new(connection: Mail.delivery_method).send(:dot_stuff?)

Mail.deliver do
from 'from@example.com'
to 'to@example.com'
subject 'dot-stuff last line'
body "this is a test\n.\nonly a test\n."
body "this is a test\n.\nonly a test\n... or is it?"
end

message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n..\nonly a test\n..")
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test\n.... or is it?")
end

it "should send emails from given settings" do
Expand Down

0 comments on commit c67129d

Please sign in to comment.