Refuse the URL-repaired spellings in the protection gate too

`isLoopbackEndpoint` hands its endpoint to `refusedByCSharpUriShape` before
`URL` sees it; `isProtectedEndpoint` did not, and `URL` repairs eleven
spellings `System.Uri` refuses outright. Every one of them answered protected
here and unprotected in the C# reference, which is the dangerous direction:
the channel-protection gate opened on a route `IsProtected` would have closed.
`wss:x`, `wss:host`, `wss:host:8443`, `wss:/host` and `wss:///host` have no
authority for `System.Uri`; `wss://host\path` and `wss://host:8443\` carry a
backslash; `wss://ho\tst/m`, `wss://host\t/m` and `quic://ho\tst` a tab, and
`wss://host\r\n/m` a CR/LF, all of which `URL` deletes.

Soul's 71 raw-shape spellings go in as a table with the answer the C#
`IsProtected` gave for each on 2026-09-16, and the test asserts the invariant
rather than equality: TypeScript may never call an endpoint protected that C#
refuses. Eleven of the 71 now differ the safe way round, C# protected and this
not, and they are pinned by name rather than excluded, so neither a twelfth
joining them nor one of them flipping passes quietly. Two throw in `URL` before
any rule of ours runs (an IPv6 zone id, a non-breaking-space host); the other
nine are host repairs `refusedByCSharpUriShape` refuses on purpose, because the
same repair would make `isLoopbackEndpoint` lie. None is dialable as a browser
CultMesh route.

The mutation that drops the pre-check from `isProtectedEndpoint` alone, leaving
`isLoopbackEndpoint`'s in place, is killed by that test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-16 18:29:13 +02:00
commit c64a2da81d
3 changed files with 147 additions and 1 deletions

View file

@ -233,6 +233,14 @@ const mutations = [
old: 'scheme.includes("quic")',
new: 'scheme === "quic"',
},
{
// Only `isProtectedEndpoint`'s copy: `isLoopbackEndpoint` keeps its own, so
// this pins that the protection gate refuses the spellings `URL` repairs
// rather than inheriting the answer from the loopback rule.
rule: "isProtectedEndpoint refuses the raw shapes System.Uri refuses",
old: " if (refusedByCSharpUriShape(value)) return false;\n let scheme: string;\n",
new: " let scheme: string;\n",
},
{
rule: "protected scheme: https",
old: 'scheme === "https" || ',