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

Error with character outside ASCII range in email address #342

Open
davidkong opened this issue Jun 5, 2024 · 3 comments
Open

Error with character outside ASCII range in email address #342

davidkong opened this issue Jun 5, 2024 · 3 comments

Comments

@davidkong
Copy link

I'm seeing errors when trying to send emails to users with non-ASCII characters in their email address. For instance the Unicode character ้.

The error is showing up here

iolist_to_binary(combine_rfc822_addresses(Addresses, [])).
with error 1st argument: not an iodata term.

(We are calling via the Elixir Swoosh library).

@adamu
Copy link
Contributor

adamu commented Aug 22, 2024

I'm also seeing this via Swoosh, but then again RFC822 designates that email-addresses must be ascii, so maybe the problem is that combine_rfc822_addresses is being called?

gen_smtp/src/mimemail.erl

Lines 992 to 1011 in 685fc92

encode_header_value(H, Value) when
H =:= <<"To">>;
H =:= <<"Cc">>;
H =:= <<"Bcc">>;
H =:= <<"Reply-To">>;
H =:= <<"From">>
->
{ok, Addresses} = smtp_util:parse_rfc5322_addresses(Value),
{Names, Emails} = lists:unzip(Addresses),
NewNames = lists:map(
fun
(undefined) ->
undefined;
(Name) ->
%% `Name' contains codepoints, but we need bytes
rfc2047_utf8_encode(unicode:characters_to_binary(Name))
end,
Names
),
smtp_util:combine_rfc822_addresses(lists:zip(NewNames, Emails));

@adamu
Copy link
Contributor

adamu commented Aug 22, 2024

Here are steps to reproduce in Elixir:

Mix.install [:swoosh, :gen_smtp, :hackney]
mail = %Swoosh.Email{to: [{"", "hello@example.com"}], from: [{"", "test@example.com"}], text_body: "test"}
Swoosh.Adapters.AmazonSES.deliver(mail)
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: not an iodata term

    :erlang.iolist_to_binary([[65352, 65349, 65356, 65356, 65359, 64, 101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109]])
    (gen_smtp 1.2.0) gen_smtp/src/smtp_util.erl:193: :smtp_util.combine_rfc822_addresses/1
    (gen_smtp 1.2.0) gen_smtp/src/mimemail.erl:963: :mimemail.encode_headers/1
    (gen_smtp 1.2.0) gen_smtp/src/mimemail.erl:964: :mimemail.encode_headers/1
    (gen_smtp 1.2.0) gen_smtp/src/mimemail.erl:210: :mimemail.encode/2
    (swoosh 1.16.12) lib/swoosh/adapters/amazon_ses.ex:226: Swoosh.Adapters.AmazonSES.generate_raw_message_data/2
    (swoosh 1.16.12) lib/swoosh/adapters/amazon_ses.ex:163: Swoosh.Adapters.AmazonSES.prepare_body/2
    iex:3: (file)

@mworrell
Copy link
Collaborator

mworrell commented Aug 26, 2024

RFC822 is quite specific that the address must be using ASCII characters. Special characters (for example quotes) in that range will be escaped.

I see in the code that non-ASCII name parts are accepted and encoded as UTF-8. The code does assume that the local-name is ASCII though.

RFC6531 does allow for unicode local-parts and domain names. A quick reading of the RFC does give me the feeling that for SMTPUTF8 support more needs to be added than just some local-part encoding.

UPDATE I see in the code that we do have SMTPUTF8 support for the server side.

From the tests:

                    ?assertMatch("250 SMTPUTF8" ++ _, Packet34),
                    smtp_socket:send(
                        CSock, <<"MAIL FROM: <испытание@пример.испытание> SMTPUTF8\r\n"/utf8>>
                    ),

So maybe it is less work than I first expected.

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

No branches or pull requests

3 participants