mail-api
mail-api copied to clipboard
Improve support for Email Address Internationalization (EAI)
EAI is defined in RFC6531 and is supported by Jakarta Mail with the SMTPUTF8 extension but some email addresses domains are considered invalid while they shouldn't when creating InternetAddress
.
To fully support EAI, InternetAddress.checkAddress
should be fixed.
We made some tests with various valid email addresses and noticed the following elements:
- if the domain part is not in normalization form NFC it is rejected
- some valid Unicode domains are not accepted
The local part is correctly handled in our test cases.
In order to fix the domain part handling, InternetAddress.checkAddress
should implement IDNA 2008 support as defined in RFC5891, an easy fix is to check the conversion of the domain to A-label with ICU4j that offers a good compliance with IDNA 2008.
Our test were done on Android and written in Kotlin with Jakarta version 2.0.1 but platform and language should not change anything here.
Here is a Kotlin snippet to check IDN conversion to A-label:
boolean isDomainValid(String domain) {
int flags = IDNA.CHECK_BIDI | IDNA.CHECK_CONTEXTJ | IDNA.CHECK_CONTEXTO | IDNA.NONTRANSITIONAL_TO_ASCII | IDNA.USE_STD3_RULES;
IDNA idna = IDNA.getUTS46Instance(flags);
IDNA.Info info = new IDNA.Info();
idna.nameToASCII(domain, new StringBuilder(), info);
return !info.hasErrors();
}
Examples of valid internationalized domains names as per IDNA 2008 but rejected by InternetAddress.checkAddress
:
- मेल.डाटामेल.top
- 𐍃𐌹𐌿𐍈𐌳𐌵𐌿.top
We might be able to use the java.net.IDN class included with the JDK to improve this.
I didn't suggest using it because it implements an old IDNA standard (IDNA 2003), so ICU is better for conformance.
@lukasj The suggestion is to use icu4j as the validation. Looks like the license file is here: https://github.com/unicode-org/icu/blob/main/icu4c/LICENSE
What are your thoughts on referencing this library? Do we want to just make the InternetAddress have some sort of service lookup instead for validation?
The only currently allowed dependency is Java SE or other jakarta API; dependency on 3rd party/non-jakarta library is not allowed
So it looks like, as you suggested, java.net.IDN would be your best option. It won't offer full compliance with the latest standard but IDNA 2003 is more permissive than IDNA 2008 and therefore would correctly handle valid Unicode domains where currently some are rejected.
Looks like we have to use the system property mail.mime.allowutf8 or create new system property should be created to deal with using old and new methods of address domain validation.