Skip to content

test(idn-email): add address-literal coverage - #1035

Open
vtushar06 wants to merge 1 commit into
json-schema-org:mainfrom
vtushar06:idn-email-address-literal
Open

test(idn-email): add address-literal coverage#1035
vtushar06 wants to merge 1 commit into
json-schema-org:mainfrom
vtushar06:idn-email-address-literal

Conversation

@vtushar06

Copy link
Copy Markdown
Contributor

Following the methodology I used for ipv4 and uuid, I read RFC 5321 section 4.1.3 and found that idn-email.json has no address-literal tests at all, while email.json has three. RFC 6531 does not change the address-literal branch, so everything email tests there applies to idn-email too.

The interesting one is the leading zero. Snum = 1*3DIGIT with the comment "representing a decimal integer value in the range 0 through 255", so the rule constrains the value and not the digit count - 01 is a legal Snum. That differs from the dec-octet rule behind format: ipv4, which forbids leading zeros, so an implementation that reuses its ipv4 checker for the bracket form gets this wrong.

Changes

  • Added 4 test cases across draft7, draft2019-09, draft2020-12, and v1.
  • δοκιμή@[192.0.2.1] - a non-ASCII local part with an IPv4-address-literal - valid.
  • δοκιμή@[IPv6:2001:db8::1] - a non-ASCII local part with an IPv6-address-literal - valid.
  • user@[192.0.2.300] - an octet over 255 inside the brackets - invalid.
  • user@[01.0.0.1] - leading zeros in an octet - valid.

Ecosystem Impact

  1. sourcemeta/core (main, 99b6a5e): PASSES all four. is_snum in src/core/email/helpers.h checks the parsed value against 255 rather than the digit count, and the comment there calls out the difference from the RFC 3986 dec-octet behind is_ipv4.
  2. go-gojsonschema v1.2.0: FAILS (rejects user@[01.0.0.1], and also [192.168.1.1] and the IPv6 form) - it does not implement the address-literal branch.
  3. java-jsonschemafriend 0.12.5: FAILS (rejects user@[01.0.0.1] and the IPv6 form).
  4. java-networknt-json-schema-validator 3.0.1: FAILS (rejects user@[01.0.0.1]).
  5. python email_validator 2.3.0: FAILS (rejects user@[01.0.0.1] even with allow_domain_literal=True) - it hands the bracket contents to Python's ipaddress.IPv4Address, which raises AddressValueError: Leading zeros are not permitted.
  6. validator.js 13.15: FAILS (rejects user@[01.0.0.1] even with allow_ip_domain: true) - same shape, a strict IPv4 pattern applied to the literal.

RFC References

Reproduction commands and the idn-email cross-implementation matrix are in my evidence repo: https://github.com/vtushar06/JSON-Schema-format-test-Evidence/blob/main/idn-email.md

Related: #965

Copilot AI review requested due to automatic review settings July 31, 2026 01:09
@vtushar06
vtushar06 requested a review from a team as a code owner July 31, 2026 01:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@jviotti jviotti 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.

Being the only one passing this made me a bit more nervous but it does seem like it's correct. Would love a second eye on this though! cc @jdesrosiers

@mwadams

mwadams commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Being the only one passing this made me a bit more nervous but it does seem like it's correct. Would love a second eye on this though! cc @jdesrosiers

You're spot on.

I was not doing address literal validation in V4 at all. V5 had an adjacent bug that was allowing invalid ASCII because it was just rejecting the disallowed IDN-rune list. So V5 was doing exactly what you're doing (and what this tests), but had a different issue!

corvus-dotnet/Corvus.JsonSchema#904

@jdesrosiers
jdesrosiers force-pushed the idn-email-address-literal branch from a67904d to bb0f904 Compare August 4, 2026 04:21
@jdesrosiers

Copy link
Copy Markdown
Member

Snum = 1*3DIGIT with the comment "representing a decimal integer value in the range 0 through 255", so the rule constrains the value and not the digit count - 01 is a legal Snum.

I'm not sure I agree with that logic. The comment is adding additional constraints to the abnf. It says that the value represents and integer. Integers aren't represented with preceding zeros. Just like the comment restricts the value to represent numbers more that 255, I think it also restricts leading zeros.

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.

5 participants