-
Notifications
You must be signed in to change notification settings - Fork 5k
url: reject special-scheme hosts made only of IDNA-ignored code points #37167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
54935d4
8154314
22044db
14ed7ef
ec82ee6
10ea67a
0b20ff5
3c1dd0f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -121,11 +121,16 @@ | |
| // Non-special schemes and '['-prefixed (IPv6) hosts never run IDNA. | ||
| String mappedValue; | ||
| if (fullURL.hasSpecialScheme() && !value.startsWith('[')) { | ||
| size_t hostEnd = value.reverseFind(':'); | ||
| auto hostSpan = hostEnd == notFound ? value : value.left(hostEnd); | ||
| size_t terminator = Bun::findURLHostTerminator(value); | ||
| size_t hostEnd = value.left(terminator).reverseFind(':'); | ||
| size_t hostSpanEnd = hostEnd == notFound ? terminator : hostEnd; | ||
| auto hostSpan = value.left(hostSpanEnd); | ||
| if (Bun::containsUnicode16IDNADeltaSource(hostSpan)) { | ||
| auto mappedHost = Bun::applyUnicode16IDNADelta(hostSpan.toString()); | ||
| mappedValue = hostEnd == notFound ? mappedHost : makeString(mappedHost, value.substring(hostEnd)); | ||
| // A host mapping to empty is a failed host parse, not an assignable literal "". | ||
| if (mappedHost.isEmpty()) | ||
| return; | ||
| mappedValue = makeString(mappedHost, value.substring(hostSpanEnd)); | ||
|
Check failure on line 133 in src/jsc/bindings/URLDecomposition.cpp
|
||
|
Comment on lines
128
to
+133
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 The Extended reasoning...What
Step-by-step proofWith
Node v26 on the same input: basic URL parser strips Pre-#34660 Bun also no-opped: there was no delta pre-scan,
Why the existing guards don't catch it
Impact
FixEither strip tab/CR/LF from |
||
| value = mappedValue; | ||
| } | ||
| } | ||
|
|
@@ -173,9 +178,17 @@ | |
| // See setHost: the input is a hostname by definition, and only special | ||
| // schemes run IDNA on it. | ||
| String mappedHost; | ||
| if (fullURL.hasSpecialScheme() && !host.startsWith('[') && Bun::containsUnicode16IDNADeltaSource(host)) { | ||
| mappedHost = Bun::applyUnicode16IDNADelta(host.toString()); | ||
| host = mappedHost; | ||
| if (fullURL.hasSpecialScheme() && !host.startsWith('[')) { | ||
| size_t terminator = Bun::findURLHostTerminator(host); | ||
| auto hostSpan = host.left(terminator); | ||
| if (Bun::containsUnicode16IDNADeltaSource(hostSpan)) { | ||
| auto mappedSpan = Bun::applyUnicode16IDNADelta(hostSpan.toString()); | ||
| // See setHost: mapping a non-empty hostname to empty is failure, not "". | ||
| if (mappedSpan.isEmpty()) | ||
| return; | ||
| mappedHost = makeString(mappedSpan, host.substring(terminator)); | ||
| host = mappedHost; | ||
| } | ||
| } | ||
| if (host.isEmpty() && !fullURL.protocolIsFile() && fullURL.hasSpecialScheme()) | ||
| return; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code