URL parsing misses several common and structurally unambiguous forms.
Gaps
http://localhost:3000/ — full-URL grammar requires an IANA TLD (src/URL.ts:95-103)
https://127.0.0.1:8443/a — no IPv4 literal support
https://[2001:db8::1]/x — no bracketed IPv6 support
https://my-site.EXAMPLE.COM/ — host labels reject hyphens (src/URL.ts:75-93), TLD matching is lowercase-only (tests/URL.test.ts:170-174 currently locks in this false negative)
- Ports use generic
number() (src/URL.ts:67-69): accepts :1.5-style input and can swallow a trailing sentence period; no 1-65535 range check
- Lone trailing
/ is dropped (src/URL.ts:70-74)
- Suffix
[^\s]+ absorbs closing quotes/brackets/periods into the URL span
Proposal
- Split authority handling: protocol-qualified URLs accept valid DNS names (with internal hyphens),
localhost, IPv4, bracketed IPv6, and internal/registered names without requiring an IANA TLD; keep the IANA-TLD requirement for bare domains only
- Case-insensitive TLD/host matching; support Punycode and Unicode labels
- Parse port as integer, validate 1-65535
- Accept a lone
/
- Scan suffix permissively, then trim clearly unmatched trailing sentence punctuation (keep balanced URL punctuation)
Tests to add
https://my-site.EXAMPLE.COM/, http://localhost:3000/, https://127.0.0.1:8443/a, https://[2001:db8::1]/x, https://münchen.de/, https://xn--mnchen-3ya.de/
See https://example.com/a). → span excludes ).
:1.5 and :65536 rejected as ports
- Flip the lowercase-only TLD expectation at
tests/URL.test.ts:170-174
Perf note
Bound labels (63), authority, and total domain length (253) while touching this grammar — see also the superlinear-scan issue for dotted non-matches.
URL parsing misses several common and structurally unambiguous forms.
Gaps
http://localhost:3000/— full-URL grammar requires an IANA TLD (src/URL.ts:95-103)https://127.0.0.1:8443/a— no IPv4 literal supporthttps://[2001:db8::1]/x— no bracketed IPv6 supporthttps://my-site.EXAMPLE.COM/— host labels reject hyphens (src/URL.ts:75-93), TLD matching is lowercase-only (tests/URL.test.ts:170-174currently locks in this false negative)number()(src/URL.ts:67-69): accepts:1.5-style input and can swallow a trailing sentence period; no 1-65535 range check/is dropped (src/URL.ts:70-74)[^\s]+absorbs closing quotes/brackets/periods into the URL spanProposal
localhost, IPv4, bracketed IPv6, and internal/registered names without requiring an IANA TLD; keep the IANA-TLD requirement for bare domains only/Tests to add
https://my-site.EXAMPLE.COM/,http://localhost:3000/,https://127.0.0.1:8443/a,https://[2001:db8::1]/x,https://münchen.de/,https://xn--mnchen-3ya.de/See https://example.com/a).→ span excludes).:1.5and:65536rejected as portstests/URL.test.ts:170-174Perf note
Bound labels (63), authority, and total domain length (253) while touching this grammar — see also the superlinear-scan issue for dotted non-matches.