mikel / mail

A Really Ruby Mail Library
MIT License
3.61k stars 936 forks source link

Error when send email with Round bracket In "From" #1573

Open huythaimanh opened 1 year ago

huythaimanh commented 1 year ago

I got this error when trying to send an SMTP email with a close round bracket (

Net::SMTPFatalError

Test SendMail ) <no-reply@test.com> Invalid email address.

If I removed the bracket (. It can send an email successfully. Test SendMail <no-reply@test.com>

Here is the log:

/usr/local/lib/ruby/2.6.0/net/smtp.rb:969→ check_response
--
/usr/local/lib/ruby/2.6.0/net/smtp.rb:937→ getok
/usr/local/lib/ruby/2.6.0/net/smtp.rb:837→ mailfrom
/usr/local/lib/ruby/2.6.0/net/smtp.rb:658→ send_message
mail-2.7.1/lib/mail/network/delivery_methods/smtp_connection.rb:54→ deliver!
mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:101→ block in deliver!
/usr/local/lib/ruby/2.6.0/net/smtp.rb:519→ start
mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:109→ start_smtp_session
mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:100→ deliver!
mail-2.7.1/lib/mail/message.rb:2159→ do_delivery
mail-2.7.1/lib/mail/message.rb:260→ block in deliver

Could the code be changed to support if we send an email with a single round bracket?

krisleech commented 1 year ago

I've had a similar problem since we get people's names from a third party which includes a department suffixed to the last name which includes square brackets.

# without 
to = "Kris Leech <kris@example.com>"
mail = Mail.new { to(to) }
mail[:to].addrs # => [#<Mail::Address:82860 Address: |Kris <kris.leech@example.com>| >]

# with
to = "Kris Leech [TECH] <kris.leech@example.com>"
mail = Mail.new { to(to) }
mail[:to].addrs # => NoMethodError: undefined method `addrs' for #<Mail::UnstructuredField

Can see it is a parse error:

mail[:to].errors # => [["To", "Kris Leech [TECH] <kris.leech@example.com>", #<Mail::Field::IncompleteParseError: Mail::AddressList can not parse |Kris Leech [TECH] <kris.leech@example.com>|: Only able to parse up to "Kris Leech ">]]

If you are constructing the "to" yourself you can quote the name part:

QuoteName = Class.new do
  extend Mail::Utilities

  def self.call(name)
    quote_phrase(name)
  end
end

to = "#{QuoteName.('Kris Leech [TECH]')} <kris@example.com>"
mail = Mail.new { to(to) }
mail[:to].addrs # => no error