Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SmtpClient: Unconditionally escape leading dots #605

Merged

Conversation

zachallaun
Copy link
Contributor

Bug: emails sent using :body and :headers do not have leading dots properly escaped. This PR fixes that. See "Reasoning" below for more info.

Breaking change

The EM::Protocols::SmtpClient :body and :headers parameters now escape leading dots on new lines.

Given the following message passed in as the :body

Hello
...world!

Old behavior: The message would be sent as-is. The recipient would see

Hello
..world!

New behavior: The leading dot in the second line would be escaped. The recipient would see

Hello
...world!

Required updates to code: If you knew about this issue and were working around it by manually escaping leading dots in data you passed to :body or :headers, you need to stop doing so to prevent double escaping.

Reasoning

cc/ @sodabrew

While discussing #600, I wrote the following:

The only change we made to the previous parameters was that leading dots in :body will now be escaped. This is not backwards-incompatible, however, because our escaping method is a no-op if the leading dots are already escaped.

Almost immediately after posting this, @davidbalbert and I realized that this decision was incorrect. Unfortunately, the PR had been merged before we could post. Sorry, @sodabrew!

The escaping mechanism for leading dots in the SMTP DATA command is unconditional. I.e. if a line starts with a dot, another dot should be inserted in front of it no matter what comes after. The current implementation escapes a leading dot only if it is not followed by another dot. This is a bug: it prevents a user from sending a message where a line starts with two leading dots (the recipient would see one), three leading dots (the recipient would see two), etc. This pull request fixes that behavior by unconditionally escaping any leading dot.

This is a small breaking change: If someone has been working around the lack of escaping in :body and :headers by escaping the leading dots themselves, this change will double-escape their leading dots. Given that SmtpClient has not been updated in years and to our knowledge no one had posted about the issue of unescaped leading dots, we think it's much more likely that people are unaware of this issue and sending unescaped emails via :body and :headers rather than manually escaping their emails themselves.

@@ -321,7 +321,7 @@ def receive_rcpt_to_response
end

def escape_leading_dots(s)
s.gsub(/^\.([^.]|$)/) { "..#{$1}" }
s.gsub(/^\.(.|$)/) { "..#{$1}" }
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you still need the $1 capture here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because we need to reinsert the character caught by the wildcard . inside the capture group in the case that the leading dot is not the only character on the line.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's equivalent to s.gsub(/^\./, '..')

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're absolutely right. Going to amend the commit.

sodabrew added a commit that referenced this pull request Jun 21, 2015
SmtpClient: Unconditionally escape leading dots
@sodabrew sodabrew merged commit 45db519 into eventmachine:master Jun 21, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants