Skip to content

Commit 889b7b2

Browse files
Fix header decoding to correctly handle multiple recipients
1 parent 59b78d1 commit 889b7b2

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

lib/mail/parsers/rfc_2822.ex

+20-15
Original file line numberDiff line numberDiff line change
@@ -405,21 +405,6 @@ defmodule Mail.Parsers.RFC2822 do
405405
defp decode_header_value(_key, %DateTime{} = datetime, _opts),
406406
do: datetime
407407

408-
defp decode_header_value("received", value, _opts),
409-
do: value
410-
411-
defp decode_header_value(_key, [value | [param | _params] = params], opts)
412-
when is_binary(value) and is_tuple(param) do
413-
decoded = parse_encoded_word(value, opts)
414-
params = Enum.map(params, fn {param, value} -> {param, parse_encoded_word(value, opts)} end)
415-
[decoded | params]
416-
end
417-
418-
defp decode_header_value(_key, {name, email}, opts) do
419-
decoded = parse_encoded_word(name, opts)
420-
{decoded, email}
421-
end
422-
423408
defp decode_header_value(key, addresses, opts)
424409
when key in ["to", "cc", "from", "reply-to"] and is_list(addresses) do
425410
addresses =
@@ -435,8 +420,28 @@ defmodule Mail.Parsers.RFC2822 do
435420
addresses
436421
end
437422

423+
defp decode_header_value("from", {_name, _address} = value, opts) do
424+
[from] = decode_header_value("from", [value], opts)
425+
from
426+
end
427+
438428
defp decode_header_value("from", value, _opts), do: value
439429

430+
defp decode_header_value("received", value, _opts),
431+
do: value
432+
433+
defp decode_header_value(_key, [value | [param | _params] = params], opts)
434+
when is_binary(value) and is_tuple(param) do
435+
decoded = parse_encoded_word(value, opts)
436+
params = Enum.map(params, fn {param, value} -> {param, parse_encoded_word(value, opts)} end)
437+
[decoded | params]
438+
end
439+
440+
defp decode_header_value(_key, {name, email}, opts) do
441+
decoded = parse_encoded_word(name, opts)
442+
{decoded, email}
443+
end
444+
440445
defp decode_header_value(_key, value, opts) do
441446
parse_encoded_word(value, opts)
442447
end

test/mail/parsers/rfc_2822_test.exs

+14
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,20 @@ defmodule Mail.Parsers.RFC2822Test do
192192
assert Mail.get_html(message) == html_part2
193193
end
194194

195+
test "parses a message with multiple recipients" do
196+
# Multiple recipients where some have names can be interpreted as a header value with params if not handled correctly.
197+
message =
198+
parse_email("""
199+
200+
""")
201+
202+
assert message.headers["to"] == [
203+
204+
{"John Doe", "[email protected]"},
205+
206+
]
207+
end
208+
195209
test "to_datetime/1" do
196210
import Mail.Parsers.RFC2822, only: [to_datetime: 1]
197211

0 commit comments

Comments
 (0)