bug PR-5.4-dev Pending

User tests: Successful: Unsuccessful:

avatar joomdonation
joomdonation
13 Mar 2026

Pull Request resolves # .

  • I read the Generative AI policy and my contribution is either not created with the help of AI or is compatible with the policy and GNU/GPL 2 or later.

Summary of Changes

MailHelper::isEmailAddress() calls PunycodeHelper::toPunycode() to convert the domain to punycode. When the domain contains forbidden characters, that method throws an exception.

The exception is not caught in MailHelper::isEmailAddress(), causes the application execution to stop. This is not the expected behavior. The method should return false for invalid email addresses instead.

Testing Instructions

  • Open templates/cassiopeia/index.php, add this line of code below somewhere in the file:
var_dump(\Joomla\CMS\Mail\MailHelper::isEmailAddress('tuanpn@exam' . "\xC2\xA0" . 'ple.com'));
  • Access to frontend of your site

Actual result BEFORE applying this Pull Request

  • You get error page with error message like this: 101 Prohibited input U+000000A0

Expected result AFTER applying this Pull Request

  • No error page. You see something like bool(false) in the place you added the code above

Link to documentations

Please select:

  • Documentation link for guide.joomla.org:

  • No documentation changes for guide.joomla.org needed

  • Pull Request link for manual.joomla.org:

  • No documentation changes for manual.joomla.org needed

avatar joomdonation joomdonation - open - 13 Mar 2026
avatar joomdonation joomdonation - change - 13 Mar 2026
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 13 Mar 2026
Category Libraries
avatar tecpromotion tecpromotion - change - 13 Mar 2026
Title
[5,4] Fix MailHelper::isEmailAddress() throwing exception for forbidden characters
[5.4] Fix MailHelper::isEmailAddress() throwing exception for forbidden characters
avatar tecpromotion tecpromotion - edited - 13 Mar 2026
avatar laoneo
laoneo - comment - 13 Mar 2026

Can be counted as BC break.

avatar joomdonation
joomdonation - comment - 13 Mar 2026

Can be counted as BC break.

@laoneo Not sure how this could be counted as BC break? The method always expect false returned when invalid email address passed, not an Exception. You want to keep the current code to have Exception throws here?

Just for information, I noticed this issue because in my extensions, I use MailHelper::isEmailAddress to validate if an email address is valid before sending emails. In case customer enter a typo in the address, for example test@domain,com, the method throws Exception and cause the whole process stopped, not something anyone would expect.

avatar laoneo
laoneo - comment - 13 Mar 2026

It doesn't matter about the return value, important is that the behavior changes in a library class, then it is a bc break. It is legit to throw exceptions in a function. When I have the code:

try {
\Joomla\CMS\Mail\MailHelper::isEmailAddress($email);
} catch (Exception $e) {
// Send here a message to the admin
}

It will not work anymore. I don't say that the pr is wrong, but it can be counted as bc break.

avatar joomdonation
joomdonation - comment - 13 Mar 2026

Is that really a real life use-case ? I would say that the method never throws Exception (it is not mentioned in doc block). I think the Exception was introduced by mistake when we start using PunycodeHelper::toPunycode() in the method but no one noticed about it

Serious, no developer would want to use try catch to check if an email is valid.

avatar laoneo
laoneo - comment - 13 Mar 2026

Technically it is a bc break, doesn't really matter if it is used or not. Anyway, I just wanted to highlight it, at the end of the day it is up to the RM to decide if they want to add it to the release or not.

avatar joomdonation
joomdonation - comment - 13 Mar 2026

I would agree if the Exception is included in the doc block of the method, but it is not in this case. Does not catch the Exception and have it thrown will make developer's life harder, with ugly code. Anyway, I will leave it to RM to decide

avatar Fedik
Fedik - comment - 13 Mar 2026

I think the fix is fine.
yea someone can have a try/catch work around, but they also should handle false case, no b/c for me.

avatar joomdonation
joomdonation - comment - 13 Mar 2026

Thanks @Fedik

avatar exlemor exlemor - test_item - 14 Mar 2026 - Tested successfully
avatar exlemor
exlemor - comment - 14 Mar 2026

I have tested this item ✅ successfully on d385651

I was able to test this successfully! Thanks @joomdonation! :)


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/47376.

avatar krishnagandhicode krishnagandhicode - test_item - 14 Mar 2026 - Tested successfully
avatar krishnagandhicode
krishnagandhicode - comment - 14 Mar 2026

I have tested this item ✅ successfully on d385651

Tested successfully, The PR does what the description says.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/47376.

avatar alikon alikon - change - 14 Mar 2026
Status Pending Ready to Commit
avatar alikon
alikon - comment - 14 Mar 2026

RTC


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/47376.

avatar richard67
richard67 - comment - 14 Mar 2026

From reading the code in the MailHelper and the PunycodeHelper I would agree with @joomdonation and @Fedik that obviously the method shall return false in case of the email address not being valid, and that the PunycodeHelper helper throws an exception now might be the result of a former update of the "Algo26\IdnaConvert" dependency.

So if extension developers have caught the exception, they still had to check the result for being true in addition in their code, so this PR here will not break anything for them except of the try catch being obsolete.

avatar muhme
muhme - comment - 15 Mar 2026

✅ final test before merge with JBT

  • Tested before PR
    • user@example.com - true
    • user.example.com - false
    • user@exa mple.com - false
    • user@exam!ple.com - false
    • test@domain,com - false
    • user@exam\xC2\xA0ple.com - exception Prohibited input U+000000A0
  • Applied PR with Patch Tester
    • Same results, unless no exception on prohibited input, it results also in false

I would agree with @richard67 and the others. This is not a B/C break, because checking the return value of isEmailAddress() (true/false) was already required before. Throwing an exception here is actually a bug.

avatar muhme muhme - change - 15 Mar 2026
Labels Added: RTC bug PR-5.4-dev
avatar muhme muhme - change - 15 Mar 2026
Status Ready to Commit Closed
Closed_Date 0000-00-00 00:00:00 2026-03-15 12:15:59
Closed_By muhme
avatar muhme muhme - close - 15 Mar 2026
avatar muhme muhme - change - 15 Mar 2026
Status Closed New
Closed_Date 2026-03-15 12:15:59
Closed_By muhme
Labels Removed: RTC
avatar muhme muhme - change - 15 Mar 2026
Status New Pending
avatar muhme muhme - reopen - 15 Mar 2026
avatar muhme muhme - close - 15 Mar 2026
avatar muhme muhme - merge - 15 Mar 2026
avatar muhme muhme - change - 15 Mar 2026
Status Pending Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2026-03-15 12:16:30
Closed_By muhme
avatar muhme
muhme - comment - 15 Mar 2026

Thank you @joomdonation for your contribution. Thank you @laoneo for supporting this issue. Thank you @exlemor and @krishnagandhicode for testing. Thank you @richard67 for review.

Add a Comment

Login with GitHub to post a comment