Reject empty labels in idn-hostname format - #1274
Conversation
RFC5892.isValid skipped empty labels with continue, so a leading or interior empty label -- ".example" or "a..b" -- validated as a valid idn-hostname. String.split already drops trailing empty labels, so the skip only ever hit leading/interior empties, which are invalid. Reject them.
There was a problem hiding this comment.
Pull request overview
Updates idn-hostname format validation to reject hostnames containing leading or interior empty labels (e.g. .example, a..b), aligning behavior with the JSON-Schema-Test-Suite and reference validators.
Changes:
- Change
RFC5892.isValidto fail fast on empty labels produced by splitting hostnames into labels. - Add a unit test asserting
.exampleanda..bare invalid while ordinary hostnames remain valid.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/main/java/com/networknt/schema/utils/RFC5892.java | Tightens IDN hostname validation by rejecting empty labels during label iteration. |
| src/test/java/com/networknt/schema/FormatValidatorTest.java | Adds regression coverage for invalid empty-label idn-hostname inputs and confirms valid hostnames still pass. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| for (String label : labels) { | ||
| if (label.isEmpty()) continue; // A DNS entry may contain a trailing '.'. | ||
| // String.split() drops trailing empty strings, so a trailing '.' never | ||
| // produces an empty label here. A leading or interior empty label | ||
| // (e.g. ".example" or "a..b") is invalid. | ||
| if (label.isEmpty()) return false; |
| // A leading or interior empty label (a leading dot, or two adjacent dots) is invalid. | ||
| assertFalse(schema.validate("\".example\"", InputFormat.JSON, | ||
| ec -> ec.executionConfig(c -> c.formatAssertionsEnabled(true))).isEmpty()); | ||
| assertFalse(schema.validate("\"a..b\"", InputFormat.JSON, | ||
| ec -> ec.executionConfig(c -> c.formatAssertionsEnabled(true))).isEmpty()); |
String.split returns an empty array for a value that is all separators
("..." or "。。"), so the loop was skipped and it validated as true. Reject
when there are no labels; this also subsumes the single-separator case.
|
Good catch. A value that is only separators ( |
The
idn-hostnameformat accepts host names with a leading or interior empty label:RFC5892.isValidskips empty labels withcontinue, with a comment about a trailing.. ButString.splitalready drops trailing empty strings, so the skip only ever hits a leading or interior empty label, both of which are invalid. Rejecting them matches the JSON-Schema-Test-Suite (idn-hostname.json: "leading dot" and "empty label between two dots is invalid") and the reference validator. Ordinary host names (and trailing dots) are unaffected; the full suite stays green (added a test).