James Hulme
James Hulme

Reputation: 53

Typos in names causing SMTP syntax errors in to field

We have a rails app that can send emails to people. We're using the mail gem (v2.7.1)

Some of the users are typoing their names - not their email addresses - in ways that are causing syntax errors when we try and send the email.

Here are some examples, one that works fine, and two different failing examples - names have been changed, but the typos have been kept the same

Working:

to = "\"Joe Bloggs\" <[email protected]>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "Joe Bloggs" <[email protected]>>>

Failure 1:

to = "\"Joe B\"log-gs\" <[email protected]>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "Joe B"log-gs" <[email protected]>>>

Falure 2:

to = "\"JOE BLOGGS\\\" <[email protected]>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "JOE BLOGGS\" <[email protected]>>>

When we try and send the failures we get the error:

Net::SMTPSyntaxError: 501 Syntax error in parameters
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:969 in check_response
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:937 in getok
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:837 in mailfrom
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:658 in send_message
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp_connection.rb:54 in deliver!
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:101 in block in deliver!
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:519 in start
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:109 in start_smtp_session
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:100 in deliver!
/gems/mail-2.7.1/lib/mail/message.rb:276 in deliver!

I've tried to find out what the allowed characters in the to are, but I haven't been able to find it.

I'm wondering if there is something we could do escape the characters, I tried CGI.escape but it didn't seem to have the effect I wanted

"%22JOE+BLOGGS%5C%22+%3Cjoe.bloggs%40example.com%3E"
#<Mail::Message:92412660, Multipart: false, Headers: <To: %22JOE+BLOGGS%5C%22+%3Cjoe.bloggs%40example.com%3E>>

Upvotes: 2

Views: 66

Answers (1)

calebkm
calebkm

Reputation: 1033

The email address "to" standards are defined by the IETF in RFC 822 which was authored in 1982 (!!) and is a bit of a slog to read through. Here are some condensed details explaining the email address format a bit more clearly.

My suggestion would be to create your own "email address formatter" helper method that strips the inputs from customers of any illegal characters. There are lots of opinions on the best regex for formatting email addresses themselves (without the name) in Ruby - a great place to test out ideas is Rubular.com.

For your appliaction, a place to start might look something like:

def format_email(str)
  email = str.match(/<(.*?)>/)[0]
  name = str.remove(email).gsub(/[^a-z0-9\s]/i, '').strip

  "#{name} #{email}"
end

This method first pulls the email out of the string by grabbing anything between the two angle brackets <..>. It then finds the name by removing the matched email from the string, then removing any non alphanumeric chars, and finally stripping any whitespace left from the ends.

Using the examples you provided this method will produce:

format_email "\"Joe Bloggs\" <[email protected]>"
=> "Joe Bloggs <[email protected]>"

format_email "\"Joe B\"log-gs\" <[email protected]>"
=> "Joe Bloggs <[email protected]>"

format_email "\"JOE BLOGGS\\\" <[email protected]>"
=> "JOE BLOGGS <[email protected]>"

You'll probably want to make this little method more verbose by actually checking the format of the email address itself, making sure we're not removing anything important from the name, etc. This is just a quick and simple example to get the creative email formatting juices flowing :-)

Upvotes: 1

Related Questions