Repository navigation
Bump WebKit (oven-sh/WebKit#909 preview): IPv6 hosts follow the IPv6 parser of the URL Standard - #47236
Bump WebKit (oven-sh/WebKit#909 preview): IPv6 hosts follow the IPv6 parser of the URL Standard#47236robobun wants to merge 2 commits into
Conversation
The preview is main's pin fcc1ea0973a4 plus two commits in URLParser::parseIPv6Host: a compressed IPv6 address takes an IPv4 tail at piece 5, and an address that ends with a single ':' does not parse. The merged commit replaces the preview tag before this leaves draft.
An IPv6 host that ends with a single colon does not parse. A compressed IPv6 host with an IPv4 address at the end parses. new URL, URL.parse, URL.canParse, the href, host and hostname setters, Request, WebSocket, fetch, URLPattern inputs, url.domainToASCII and url.domainToUnicode all reach the same host parser. Every expected value is also what Node.js v26.3.0 gives. The url.domainToUnicode loop over the invalid inputs called url.domainToASCII. It calls url.domainToUnicode now.
|
Status: waiting for oven-sh/WebKit#909, which has the fix. This pull request pins its preview build and adds the tests. Reproduced on Bun 1.4.3 and on main ( console.log(new URL("http://[::1:]/").href); // http://[::1]/ Node.js v26.3.0 throws
try { new URL("http://[2001:db8:1234::5efe:127.0.0.1]/"); } catch (e) { console.log(e.code); } // ERR_INVALID_URL Node.js parses it
CI on Main's pin has moved several times since that build, so this branch conflicts on the |
Draft until oven-sh/WebKit#909 merges.
WEBKIT_VERSIONis its preview build: the fork commitfcc1ea09, which main pinned when this was opened, plus two commits. The merged commit replaces it before this leaves draft.Problem
new URL("http://[::1:]/")giveshttp://[::1]/, andfetch("http://[::1:]:3000/")connects to[::1]. The URL Standard says failure. Node.js, Chromium and rust-url refuse the URL.new URL("http://[2001:db8:1234::5efe:127.0.0.1]/")throws. The URL Standard parses it.URLParser::parseIPv6Hostin WTF (vendor/WebKit/Source/WTF/wtf/URLParser.cpp:3293,:3332).Fix
url.test.ts,urlpattern.test.tsandurl-domain-ascii-unicode.test.js.bun bd teston the three files gives 5 failures on main's pin and 574 passes with this pin.test/js/web/url,test/js/web/urlpatternandtest/js/node/url: 765 pass, 0 fail.url.domainToUnicodeloop over invalid inputs calledurl.domainToASCII. It now callsurl.domainToUnicode.Background
::(a compression) is a run of zero pieces.WTF::URL, so one parser covers them all.z.ipv6()usesURL.canParse, so it accepts::1:on Bun.URLDecomposition.cpp: it cannot cover the constructor or URLPattern.Downsides
:no longer parses.new URLthrows,fetchrejects and a setter keeps the old host, as in Node.js.Notes
Repro.
http://[::1:]/http://[::1]/http://[1::2:]:81/http://[1::2]:81/http://[1:2:3:4:5:6:7:]/http://[1::]/http://[1::]/http://[1::]/http://[2001:db8:1234::5efe:127.0.0.1]/http://[2001:db8:1234::5efe:7f00:1]/The contract. URL Standard, IPv6 parser. After a piece and a
:: "If c is the EOF code point, IPv6-invalid-code-point validation error, return failure." For an IPv4 address at the end, the position check is: "If pieceIndex is greater than 6, IPv4-in-IPv6-too-many-pieces validation error, return failure." WTF parses the first case and drops the colon (upstream chose that in 2019, bug 199627, on a wrong reading of the standard). It rejects the second case when a compression leaves the IPv4 address at piece 5. oven-sh/WebKit#909 has the history and the measurements.The pin.
autobuild-preview-pr-909-c061b103isfcc1ea0973a4plus two commits: the commit of oven-sh/WebKit#648 (the IPv4 tail) and the trailing colon fix. If a WebKit upgrade brings the merged commits to main first, this pull request drops the pin change and keeps the tests.Tests.
test/js/web/url/url.test.ts: two tests. The rejected hosts go throughnew URL,URL.parse,URL.canParse, a base URL, thehref,hostandhostnamesetters,Request,WebSocketandfetch. Controls: a final::stays valid, and the setters still take a valid bracketed value.test/js/web/urlpattern/urlpattern.test.ts: a URL input, a hostname input and a base URL with the trailing colon do not match.test/js/node/url/url-domain-ascii-unicode.test.js:[::1:]gives""fromurl.domainToASCIIandurl.domainToUnicode. The five older rows of that table were never checked againsturl.domainToUnicode, because its loop calledurl.domainToASCII. They pass.Every expected value is also what Node.js v26.3.0 gives. The five failures on main's pin are the two tests in
url.test.ts, the URLPattern test, and the[::1:]row in each of the twodescribeblocks.How much differs from Node.js. 334,619 bracketed hosts (every string of length 0 to 8 over
0 1 : ., 300,000 random token strings, and a structured set), each parsed by Bun and by Node.js v26.3.0. Bun 1.4.3 differs on 488. The debug build of this branch differs on 0.Other suites. The 42
test-url*andtest-whatwg-url*files of the Node.js suite give the same exit codes as before.[policy-decision:webkit] gate passed · iteration 0 · 4 files touched
passes on PR (with fix)
diff hotspot
gate history · 1 passed · 0 rejected · iteration 0
evidence per changed file