fix(fqdn): reject domain labels with a trailing hyphen - #1592
Conversation
| {"24.example24.com", true}, | ||
| {"test.24.example.com", true}, | ||
| {"test-site-http.test-site", true}, | ||
| {"foo-.example.com", false}, |
There was a problem hiding this comment.
Perhaps some test cases confirming label length (63 characters) would be helpful as an addition to the test suite? I believe the regex seems correct, but it may be beneficial for future contributors, what do you think?
There was a problem hiding this comment.
Great point!
I agree that having explicit boundary tests will be really helpful for future contributors and prevent regressions.
|
Added cases for a 63-char label (passes, the RFC max a single label can be) and 64 (fails). TestFQDNValidation passes. |
fqdnRegexStringRFC1123 matched each label with
[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62}, which allows a label to end in a
hyphen (e.g. "foo-.example.com" or "example.com-"). The hostname
validators were fixed for the same issue in go-playground#1565 (RFC 1123) and go-playground#1569
(RFC 952), but the fqdn pattern, whose comment says it should match
hostnameRegexStringRFC1123, was left behind.
Use the same label shape [a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? so
a label must start and end with an alphanumeric. The non-numeric TLD,
the optional trailing dot, and hyphens inside the last label (go-playground#1548) are
preserved.
47c584f to
44963db
Compare
The existing boundary cases only exercise the first label. The FQDN pattern matches the first label, the middle labels and the TLD with three separate groups, so a 63/64 pair on the first one says nothing about the other two. Adds the same pair at both remaining positions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@georgepsarakis @nodivbyzero — done in The branch already had a 63/64 pair, but only on the first label: {strings.Repeat("a", 63) + ".com", true},
{strings.Repeat("a", 64) + ".com", false},The pattern matches a hostname with three separate groups: the first label, the middle labels, and the TLD. Each carries its own Measured against the pattern before writing anything, so the expectations are observations rather than guesses: Added the missing four: {"foo." + strings.Repeat("a", 63) + ".com", true},
{"foo." + strings.Repeat("a", 64) + ".com", false},
{"foo." + strings.Repeat("a", 63), true},
{"foo." + strings.Repeat("a", 64), false},And checked that they constrain something, by widening the middle-label quantifier from Index 21 is the new 64-character middle-label case. Before this commit that mutation passed the suite. On the red The workflow pins |
Fixes Or Enhances
The
fqdnvalidator accepts domain labels that end in a hyphen, even though those are not valid hostnames. All of these pass today but shouldn't:foo-.example.com(first label ends in a hyphen)foo.bar-.com(middle label ends in a hyphen)example.com-(TLD ends in a hyphen)fqdnRegexStringRFC1123matches each label with[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62}, i.e. one alphanumeric followed by up to 62 of[a-zA-Z0-9-], so nothing forces the last character of a label to be alphanumeric.The hostname validators had the same issue and were fixed in #1565 (RFC 1123) and #1569 (RFC 952), which changed each label to
[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?. The fqdn pattern was not updated at the same time, even though its comment says it is "same as hostnameRegexStringRFC1123 but must contain a non numerical TLD". This PR applies that same label shape to the fqdn pattern, including the TLD (which still has to start with a letter).Behaviour that stays the same: the non-numeric TLD requirement, the optional trailing dot, and hyphens inside the last label added in #1548 (
test-site-http.test-sitestill validates). I diffed the new pattern against the old one over a large set of random label strings; the only inputs whose result changes are the ones with a label ending in a hyphen.Added regression cases to
TestFQDNValidationand ran the package tests locally.Make sure that you've checked the boxes below before you submit PR:
@go-playground/validator-maintainers