Reject non-ASCII whitespace in idn-email and strengthen email format tests - #1268
Conversation
…tests Follow-up to networknt#1267 applying the review suggestions: - Extract the non-ASCII-whitespace check to Strings.containsNonAsciiWhitespace and reuse it from both EmailFormat and IdnEmailFormat. - idn-email shares EmailFormat's delegation and had the same bug (a leading U+00A0 was accepted); it now rejects non-ASCII whitespace too. Adds a license header to IdnEmailFormat (it had none) and a new IdnEmailFormatTest that also verifies a non-ASCII letter is still accepted. - Strengthen EmailFormatTest: assert a quoted local part with an ASCII space ("joe bloggs"@example.com) stays valid, and generalize the negative case over U+00A0, U+2003 and U+3000. The change stays deliberately narrow (whitespace only); non-ASCII letters are still accepted in idn-email. Zero-width format characters (e.g. U+200B, U+FEFF) are out of scope and unchanged.
|
Thanks for the quick review and merge on #1267, @stevehu 🙏 This follow-up applies the suggestions from that review:
Two judgment calls I flagged in the description: I kept |
|
Local checkout restored to master, working tree clean. Review: PR #1268 — Reject non-ASCII whitespace in idn-email networknt/json-schema-validator · followup/1267-email-idn-whitespace → master · +146 / −18 across 5 files · by @el-psy-kongroo-d Overview Follow-up to #1267, which fixed email rejecting a leading U+00A0 but left the sibling idn-email with the identical bug. This PR:
Verification I built the branch and ran things rather than reading only:
┌──────────────┬────────┬────────┬────────┬────────┬──────────┬────────┬────────┐ This validates the isSpaceChar half of the disjunction — the three non-breaking separators are precisely the ones isWhitespace alone misses, and U+00A0 was the reported bug. The javadoc explaining why both predicates are needed is accurate and worth keeping.
Code quality Genuinely good. Specific things done right:
Suggestions
Risks Low. The behavior change is narrow and in the stricter direction, applied to a format that was accepting input the spec doesn't permit. The main compatibility consideration is that anyone relying on idn-email accepting a leading non-breaking space now gets a validation error — which is the point of the fix. The deliberate exclusion of Cf characters (U+200B, U+FEFF) keeps the blast radius small and is documented in both the PR body and the javadoc. No security concerns: no new parsing, no regex (so no ReDoS surface), no I/O, and the guard is a pure function that runs before the existing validator rather than replacing it. Recommendation: approve. Suggestion 1 is the only one I'd bother asking for, and it's optional. |
|
Thanks for the thorough review. This was my first open-source contribution, and going through the whole cycle — issue, a narrowly-scoped fix, review, and a follow-up applying the suggestions — taught me a lot about how contribution actually works. Added the parameterized U+2003 / U+3000 case to Looking forward to contributing more. |
|
Local checkout restored to master, working tree clean. Re-review: PR #1268 after commit 13a0af4 networknt/json-schema-validator · followup/1267-email-idn-whitespace → master · +160 / −18 across 5 files · by @el-psy-kongroo-d What changed since my last review Exactly one commit, doing exactly what suggestion 1 asked and nothing else: 13a0af4 Generalize idn-email whitespace test over U+2003 and U+3000 +14 / −0 in IdnEmailFormatTest.java — two imports and the mirrored @ParameterizedTest @valuesource(ints = { 0x2003, 0x3000 }) case. No main-source changes, so the behavior surface is identical to the version I already verified. Suggestions 2–4 were left alone, which is the right call — each was explicitly marked optional or a maintainer-preference item. Verification
┌───────────────────────────────────┬─────────┬───────────┐ The two columns are now identical for every case, which is the whole point of the PR. The Cf row is the documented scope boundary holding, and the NEL row is the underlying validator catching what the guard deliberately doesn't.
Remaining notes (none blocking)
Risks Unchanged from my last pass: low. Narrow, stricter-direction behavior change on input the spec doesn't permit; no new parsing, no regex, no I/O; pure function running ahead of the existing validator. Recommendation: approve and merge. The follow-up addressed the one suggestion I'd have asked for, the fix is verified load-bearing by mutation, and the full suite is green. Also worth saying: for a first open-source contribution, splitting the narrow fix from the follow-up refactor, pre-empting the license-header question with evidence in the PR body, and building invisible characters from code points instead of pasting them into source are all things regular contributors get wrong. |
Follow-up to #1267, applying the review suggestions from that PR.
Changes
Strings.containsNonAsciiWhitespaceand reuse it from both
EmailFormatandIdnEmailFormat(instead of a privatehelper in a single class).
IdnEmailFormatsharesEmailFormat's delegation and had thesame bug — a leading U+00A0 was accepted. It now rejects non-ASCII whitespace
too. Adds a new
IdnEmailFormatTest(which also asserts a non-ASCII letteris still accepted, since idn-email allows those) and a license header to
IdnEmailFormat, which previously had none.EmailFormatTest: assert a quoted local part with an ASCIIspace (
"joe bloggs"@example.com) stays valid, and generalize the negativecase over U+00A0, U+2003 and U+3000.
Scope
Deliberately narrow: only non-ASCII whitespace is rejected. Non-ASCII
letters remain valid (important for idn-email). Zero-width format characters
such as U+200B and U+FEFF (Unicode category Cf) are out of scope and unchanged
from previous behavior.
Notes on license headers
IdnEmailFormathad no header; the added one matches its siblingEmailFormat.java(Copyright (c) 2016 Network New Technologies Inc.).EmailFormatTest/IdnEmailFormatTestuseCopyright (c) 2025 the original author or authors, matching every other test file in the format package(
TimeFormatTest,UriFormatTest, ...). That is why the Reject non-ASCII whitespace in email format #1267 header nit wasnot switched to the main-source form — it would diverge from the test siblings.
Testing
Full test suite passes (8477 tests, 0 failures).