Refuse the endpoint spellings WHATWG URL repairs and System.Uri does not
`isLoopbackEndpoint` handed the raw endpoint to `URL` and read the host it got back. `URL` is a repairing parser and `System.Uri` is not, so seven spellings were loopback here and remote in C#: a trailing dot on the host, which `URL` drops; `ws:127.0.0.1`, `ws:/127.0.0.1` and `ws:///127.0.0.1`, whose authority `URL` infers; a backslash path separator, which `URL` reads as a separator; fullwidth digits and letters in the host, which `URL` folds to ASCII; and a tab in the host, which `URL` deletes. Each of those is a local-development bypass: a route the C# consumer would have demanded a certificate for opened unsigned here. `refusedByCSharpUriShape` refuses exactly those, on the raw string, before `URL` sees it. Leading and trailing C0 controls and spaces around the whole endpoint are stripped first, because both sides accept them. The spellings Hands probed earlier and C# accepts -- `127.1`, hex, decimal, `[::FFFF:7F00:1]`, userinfo, `localhost:8443` -- are untouched. The doc comment claimed equivalence with `System.Uri.IsLoopback`. It is not equivalent and now says so: two divergences remain, both unreachable from a browser CultMesh route, and both named. An IPv6 zone id throws in `URL` and is a host-local interface name no browser socket can dial; `file:` and `mailto:` have no `URL` host and are refused by `openSocket`, which takes `ws:` and `wss:` only. The test is Soul's endpoint list with the C# answer as the expectation: 82 of the 88 it probed, the six unreachable ones named in the doc comment instead. Mutations: the trailing-dot refusal dropped, the scheme-and-authority shape inverted, the backslash refusal dropped, and the non-ASCII host refusal dropped -- each killed by the table. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
c4c2330805
commit
803ee12a7a
3 changed files with 172 additions and 22 deletions
|
|
@ -188,6 +188,26 @@ const mutations = [
|
|||
old: 'host === "::ffff:7f00:1" ||',
|
||||
new: "",
|
||||
},
|
||||
{
|
||||
rule: "a trailing dot on the host is refused, as System.Uri refuses it",
|
||||
old: ' || host.endsWith(".");',
|
||||
new: ";",
|
||||
},
|
||||
{
|
||||
rule: "a scheme not followed by // and an authority is refused",
|
||||
old: " if (!shape) return true;",
|
||||
new: " if (!shape) return false;",
|
||||
},
|
||||
{
|
||||
rule: "a backslash in the endpoint is refused",
|
||||
old: ' if (raw.includes("\\\\")) return true;\n',
|
||||
new: "",
|
||||
},
|
||||
{
|
||||
rule: "a non-ASCII host is refused, so URL cannot fold a fullwidth form to ASCII",
|
||||
old: " return /[^\\u0021-\\u007e]/.test(host)",
|
||||
new: " return false",
|
||||
},
|
||||
{
|
||||
rule: "protected scheme: any scheme containing quic",
|
||||
old: 'scheme.includes("quic")',
|
||||
|
|
|
|||
Loading…
Reference in a new issue