Skip to content

Fix address with Q-encoded display name containing double quotes #841

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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/mail/constants.rb
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ module Constants
HYPHEN = '-'
COLON = ':'
ASTERISK = '*'
DOUBLE_QUOTE = '"'
CR = "\r"
LF = "\n"
CR_ENCODED = "=0D"
16 changes: 8 additions & 8 deletions lib/mail/parsers/address_lists_parser.rb
Original file line number Diff line number Diff line change
@@ -86,15 +86,15 @@ def parse(s)

# Don't set the display name until the
# address has actually started. This allows
# us to choose quoted_s version if it
# exists and always use the 'full' phrase
# us to always use the 'full' phrase
# version.
when :angle_addr_s
if qstr
address.display_name = qstr
qstr = nil
elsif phrase_e
address.display_name = s[phrase_s..phrase_e].strip
if phrase_e
phrase = s[phrase_s..phrase_e].strip
if phrase[0, 1] == DOUBLE_QUOTE && phrase[-1, 1] == DOUBLE_QUOTE
phrase = phrase[1..-2]
end
address.display_name = phrase
phrase_e = phrase_s = nil
end

@@ -110,7 +110,7 @@ def parse(s)
when :local_dot_atom_pre_comment_e
local_dot_atom_pre_comment_e = p-1
when :local_quoted_string_e
address.local = '"' + qstr + '"' if address
address.local = DOUBLE_QUOTE + qstr + DOUBLE_QUOTE if address

# obs_domain_list
when :obs_domain_list_s then obs_domain_list_s = p
2 changes: 1 addition & 1 deletion lib/mail/utilities.rb
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ def quote_token( str )
# string = 'This is "a string"'
# dquote(string #=> '"This is \"a string\"'
def dquote( str )
'"' + unquote(str).gsub(/[\\"]/n) {|s| '\\' + s } + '"'
DOUBLE_QUOTE + unquote(str).gsub(/[\\"]/n) {|s| '\\' + s } + DOUBLE_QUOTE
end

# Unwraps supplied string from inside double quotes and
22 changes: 21 additions & 1 deletion spec/mail/elements/address_spec.rb
Original file line number Diff line number Diff line change
@@ -80,6 +80,26 @@
it "should decode the display name without calling #decoded first" do
encoded = '=?ISO-8859-1?Q?Jan_Kr=FCtisch?= <jan@krutisch.de>'
expect(Mail::Address.new(encoded).display_name).to eq 'Jan Krütisch'

encoded = '=?ISO-8859-1?Q?Ja(n_Kr=FCt)isch?= <jan@krutisch.de>'
expect(Mail::Address.new(encoded).display_name).to eq 'Jaisch'
expect(Mail::Address.new(encoded).comments).to eq ['n_Kr=FCt']

encoded = '=?ISO-8859-1?Q?Jan_Kr=FCt(isc)h?= <jan@krutisch.de>'
expect(Mail::Address.new(encoded).display_name).to eq 'Jan Krüth'
expect(Mail::Address.new(encoded).comments).to eq ['isc']
end

it "should decode Q-encoded display name containing double quotes" do
encoded = '=?ISO-8859-1?Q?"Jan_Kr=FCtisch"?= <jan@krutisch.de>'
expect(Mail::Address.new(encoded).display_name).to eq '"Jan Krütisch"'

encoded = '=?ISO-8859-1?Q?Jan_Kr=FCti"s"ch?= <jan@krutisch.de>'
expect(Mail::Address.new(encoded).display_name).to eq 'Jan Krüti"s"ch'

encoded = '=?ISO-8859-1?Q?J(an)_Kr=FCti"s"ch?= <jan@krutisch.de>'
expect(Mail::Address.new(encoded).display_name).to eq 'J Krüti"s"ch'
expect(Mail::Address.new(encoded).comments).to eq ['an']
end

it "should give back the local part" do
@@ -669,7 +689,7 @@
expect(address.encoded).to eq '=?UTF-8?B?44G+44GR44KL?= <mikel@test.lindsaar.net>'
end

it "should provide an encoded output for non us-ascii" do
it "should provide a decoded output for non us-ascii" do
address = Mail::Address.new
address.display_name = "まける"
address.address = "mikel@test.lindsaar.net"