Skip to content

Require the IPv6: tag for bracketed IPv6 email literals#428

Merged
garydgregory merged 3 commits into
apache:masterfrom
sahvx655-wq:email-ipv6-literal-tag
Jul 22, 2026
Merged

Require the IPv6: tag for bracketed IPv6 email literals#428
garydgregory merged 3 commits into
apache:masterfrom
sahvx655-wq:email-ipv6-literal-tag

Conversation

@sahvx655-wq

Copy link
Copy Markdown
Contributor
  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
  • Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body.

EmailValidator.isValidDomain hands the contents of a bracketed host to InetAddressValidator.isValid, which accepts an IPv4 or an IPv6 address without distinguishing them. RFC 5321 section 4.1.3 tags an IPv6 address literal with IPv6: and leaves an IPv4 literal untagged, so the current code is wrong at both ends: it accepts a bare user@[::1], which no conformant parser should, and rejects the correctly tagged user@[IPv6:::1] because the IPv6: prefix reaches InetAddressValidator as part of the address and the parse fails. I came across it while checking why a valid IPv6 literal was being turned away when the malformed bare form validated.

The fix matches the IPv6: tag on the bracket contents, case insensitively since it is ABNF-literal text, and validates the remainder as IPv6; an untagged literal is validated as IPv4 only. Keeping the split in isValidDomain leaves the IPv4-versus-IPv6 rule in the one place that parses the bracketed host, and the deprecated validator.EmailValidator inherits it because its isValid delegates here. Left unfixed, an allow-list built on this treats a bare loopback or link-local literal that no conformant MTA routes as valid while refusing the RFC form.

@garydgregory garydgregory changed the title require the IPv6: tag for bracketed IPv6 email literals Require the IPv6: tag for bracketed IPv6 email literals Jul 21, 2026

@garydgregory garydgregory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is now a mix of RegEx and string matching. Shouldn't it be possible to update the regex and keep it at that?

@sahvx655-wq

Copy link
Copy Markdown
Contributor Author

Fair point, the regionMatches/substring pair was doing work the pattern could do itself. I've moved the tag into IP_DOMAIN_REGEX as an optional capture group, ^\[((?i)IPv6:)?(.*)\]$, so the match itself records whether the tag was present and isValidDomain just picks isValidInet6Address or isValidInet4Address based on group(1), with group(2) as the address. The (?i) is scoped to the tag group so the address part is unaffected, and the IPV6_TAG constant and string handling are gone.

Behaviour is unchanged from the previous revision: tagged literals validate as IPv6 in any case, untagged ones as IPv4 only. The new test still passes and the full default mvn goal (rat, japicmp, checkstyle, spotbugs, pmd, javadoc) is BUILD SUCCESS.

Added Javadoc comment for IP_DOMAIN_REGEX to clarify its purpose.
@garydgregory
garydgregory merged commit aeacecf into apache:master Jul 22, 2026
10 checks passed
garydgregory added a commit that referenced this pull request Jul 22, 2026
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