mail
mail copied to clipboard
Extra \r in text part
Hello!
I was just upgrading a Rails app from 5.2.1 to 5.2.2.1 which upgraded mail from 2.7.0 to 2.7.1. One of my mailer tests started failing because the text part now shows a \r at the end of every line.
I suspect this is due to d17be6676.
My mailer test looks like this:
email = UserMailer.some_notification
asssert_emails(1) { email.deliver_now }
expected = read_fixture('some_notification.text')
assert_equal expected, email.text_part.body.to_s
And the result looks like:
UserMailerTest#test_some_notification [test/mailers/user_mailer_test.rb:450]:
--- expected
+++ actual
@@ -1,16 +1,16 @@
-"Hello Billy,
-
-Blah blah blah
-
+"Hello Billy,\r
+\r
+Blah blah blah\r
+\r
"
I have several mailer methods generating multipart emails but this is the only one that fails. When I list the fixtures for the text parts, they are all ASCII apart from the failing one's which is UTF-8 (because it contains a non-ASCII character):
$ file test/fixtures/user_mailer/*.text
test/fixtures/user_mailer/foo.text: ASCII text
test/fixtures/user_mailer/bar.text: ASCII text
test/fixtures/user_mailer/baz.text: ASCII text
test/fixtures/user_mailer/some_notification.text: UTF-8 Unicode text
test/fixtures/user_mailer/qux.text: ASCII text
After reading the commit I mentioned above, and various issues mentioning CRLF, and StackOverflow posts, I'm still not sure:
- whether my test should be failing now;
- what is the correct way to get it to pass
- adjust the test?
- adjusting the way I use the mail gem?
Any help would be much appreciated!
I have the same problem with an application moving from Rails 4.2.10 to 4.2.11.1 for security updates. https://github.com/rails/rails/commit/474b7392c69852e8932260ea370cd63cf1e4fcaa#diff-e79a60dc6b85309ae70a6ea8261eaf95L140
My generated mail tests that compare to a sample text file work fine in 2.7.0, but break with 2.7.1, expecting \r\n line endings instead of \n.
Specifying mail version 2.7.0 in my gemfile avoids the issue for now.
A workaround for now is to force the encoding to Encoding::BINARY to your string by <str>.force_encoding(Encoding::BINARY) which essentially replicates what https://github.com/mikel/mail/commit/d17be66765f7f63caa5d5cedb67a597f853a4402#diff-a7c034cc00a80cf8cd50f9abee8be86fL2003 was doing.
Where in the mail processing can I insert that force_encoding() call? I tried mail.body_encoding(Encoding::BINARY) but the resulting mail was illegible. I'm on Rails 6.0 and ActionMailer demands 2.7.1 so I'm stuck there. Is there any timetable for a fix on this one?
Just drop this in config/initializers/mail_patch.rb to make mail produce RFC compliant emails again, it simply patches back the function from before the bug was introduced.
module Mail
module Encodings
class QuotedPrintable < SevenBit
def self.encode(str)
::Mail::Utilities.to_crlf([::Mail::Utilities.to_lf(str)].pack("M"))
end
end
end
end
No idea why it's taking so long, I guess plain text email is going out of fashion so very few people are bothered by it and although mail 2.7.1 violates the spec the extra /r only shows up in a few mail clients.
Thank you @Fjan that did it! Not just my ludite impulses this time, we want folks to insert edits in the replys. Thank again for the prompt day saver.
Unfortunately @Fjan's patch above didn't make any difference for me on Rails 6.0.0 and Mail 2.7.1. However this patch worked for me:
# config/initializers/mail_patch.rb
module Mail
module Utilities
def self.safe_for_line_ending_conversion?(string)
string.ascii_only?
end
end
end
I don't understand this area well enough to be confident that it's a suitable workaround, but it makes my tests pass.
@airblade I can confirm that your patch works fine, thank you! Rails 6.0.4.1, mail 2.7.1.