Skip to content

fix: support punycode TLDs in URL regex#666

Open
HardAndHeavy wants to merge 2 commits into
netbirdio:mainfrom
HardAndHeavy:add-punycode
Open

fix: support punycode TLDs in URL regex#666
HardAndHeavy wants to merge 2 commits into
netbirdio:mainfrom
HardAndHeavy:add-punycode

Conversation

@HardAndHeavy

@HardAndHeavy HardAndHeavy commented Jun 11, 2026

Copy link
Copy Markdown

Issue ticket number and link

No related issue — this is a small self-contained fix.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Internal regex fix in URL validation — no user-facing behavior or API changes, so documentation update is not required.


Summary

Update the URL validation regex to support internationalized domain names (IDN) in Punycode format.

Problem

The current regex rejects valid IDN TLDs because the TLD part only allows letters:

(([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}
//                              ^^^^^^^^
//                      only letters allowed

As a result, URLs with Punycode TLDs fail validation, even though they are perfectly valid. Examples of such TLDs:

  • .xn--p1ai
  • .xn--fiqs8s
  • .xn--qxam
  • .xn--mgba3a4f16a

Solution

Split the TLD matching into two cases:

  • Regular TLDs: letters only, 2+ chars (e.g. .com, .org, .net)
  • Punycode TLDs: xn-- prefix followed by letters, digits and hyphens (e.g. .xn--p1ai, .xn--fiqs8s)
(([a-z\d]([a-z\d-]*[a-z\d])*)\.)+([a-z]{2,}|xn--[a-z\d-]+)

Test cases

URL Before After
https://example.com
https://example.org
https://example.xn--p1ai
https://example.xn--fiqs8s
https://xn--80adjurfhd.xn--c1aao5a.xn--p1ai
http://localhost:3000
https://192.168.0.1/path

Notes

  • Backwards compatible: all previously valid URLs remain valid.
  • The fix is generic and covers all IDN TLDs that follow the Punycode encoding standard (RFC 3492), not just specific ones.
  • For production-grade TLD validation, consider using a dedicated library (e.g. tldts) with the Public Suffix List, since the set of TLDs changes over time.

Summary by CodeRabbit

  • Bug Fixes
    • Improved URL validation to support internationalized domain names by accepting Punycode-form domains (e.g., xn--...). This enhances compatibility with global domain names and reduces false negatives when entering non-ASCII domains.
    • No changes to public interfaces or exported behavior visible to users.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa781817-c617-41dc-99fc-e1927e392630

📥 Commits

Reviewing files that changed from the base of the PR and between a62e3f2 and 7cf2360.

📒 Files selected for processing (1)
  • src/utils/helpers.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/helpers.ts

📝 Walkthrough

Walkthrough

Updated isValidUrl URL-validation regex in src/utils/helpers.ts to accept Internationalized Domain Names in Punycode form by allowing xn--... TLDs alongside standard ASCII TLDs. No API changes.

Changes

Punycode Domain Support

Layer / File(s) Summary
URL validation regex for Punycode TLDs
src/utils/helpers.ts
The domain/TLD pattern in the isValidUrl regex is expanded to match Punycode TLDs (xn--[a-z\d](?:[a-z\d-]*[a-z\d])?)) alongside standard ASCII TLDs ([a-z]{2,}).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐰 I hopped through patterns, thread by thread,
Found xn-- and nodded my head.
Punycode petals in the net's bouquet,
Now names from far can come and play.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding support for Punycode TLDs in the URL validation regex.
Description check ✅ Passed The description follows the template with all required sections completed: issue reference, documentation selection with explanation, and comprehensive details on the problem, solution, and test cases.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed due to a network error.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/helpers.ts`:
- Line 133: The punycode TLD branch in the hostname regex uses the
too-permissive fragment "xn--[a-z\\d-]+", which allows labels ending with a
hyphen; update that fragment to enforce the same edge constraints as regular
labels by replacing it with "xn--[a-z\\d]([a-z\\d-]*[a-z\\d])?" so the punycode
label cannot start or end with a hyphen (refer to the existing label pattern
([a-z\\d]([a-z\\d-]*[a-z\\d])*) to mirror its behavior).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: da7fb532-2206-4e6a-be2f-9eedf30684ab

📥 Commits

Reviewing files that changed from the base of the PR and between 1d8d32d and a62e3f2.

📒 Files selected for processing (1)
  • src/utils/helpers.ts

Comment thread src/utils/helpers.ts Outdated
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

Successfully merging this pull request may close these issues.

2 participants