Skip to content

fix: parse relative URLs with multiple leading slashes for special schemes#1137

Closed
ZachDreamZ wants to merge 1 commit into
servo:mainfrom
ZachDreamZ:fix/parse-relative-multiple-slashes
Closed

fix: parse relative URLs with multiple leading slashes for special schemes#1137
ZachDreamZ wants to merge 1 commit into
servo:mainfrom
ZachDreamZ:fix/parse-relative-multiple-slashes

Conversation

@ZachDreamZ

Copy link
Copy Markdown

What's wrong

When a relative URL starts with more than two slashes (e.g. ///test) and the base URL has a special scheme (http, https, ws, wss, ftp), the parser throws an error instead of correctly parsing it.

Url::options().base_url(Some(&Url::parse("http://example.org/").unwrap()))
    .parse("///test")
    .unwrap()
// Expected: http://test/
// Actual: Err(EmptyHost)

This matches Chrome, Firefox, Node, and Bun behavior. The URL spec's special authority slashes state says all leading slashes should be consumed before parsing the authority.

What this does

In parse_relative, when we have a base URL with a special scheme, we now route directly to after_double_slash with the remaining input, which correctly handles multiple leading slashes. The existing split_prefix("//") path is kept for non-special schemes.

Also removed 7 entries from expected_failures.txt that now pass correctly:

  • ///test against http://example.org/
  • ///example.org/path against http://example.org/
  • and 5 more variants

Test plan

  • All existing WPT tests should pass
  • The 7 removed expected failures should now be correct
  • Verified against the WPT test data for scheme-relative paths with multiple slashes

Context

This was previously reported as denoland/deno#35172 where new URL("///test", "http://example.org") throws in Deno but works in all other browsers and runtimes.

…hemes

When a relative URL starts with more than two slashes (e.g. ///test)
and the base has a special scheme (http, https, ws, wss, ftp), the
parser should consume all leading slashes before parsing the authority,
matching the URL spec's special authority slashes state.

Previously, split_prefix("//") only consumed exactly two slashes,
leaving the remaining slash to be parsed as part of the authority,
which caused an empty host error for inputs like ///test with base
http://example.org/.

This fix adds a check for special schemes before the split_prefix
call, routing directly to after_double_slash which handles the
remaining input correctly.

Fixes URL parsing for:
  new URL('///test', 'http://example.org/') -> http://test/
  new URL('///example.org/path', 'http://example.org/') -> http://example.org/path

Removed 7 entries from expected_failures.txt that now pass correctly.
@mrobinson

Copy link
Copy Markdown
Member

Duplicate of #1136.

@mrobinson mrobinson closed this Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants