Description
- Version: v15.4.0
- Platform:
Linux 5b80145d2618 4.19.0-13-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64 GNU/Linux
- Subsystem:
What steps will reproduce the bug?
Parse a relative-URL string that begins with a backslash. For example:
> new URL("\\x", "https://example/foo/bar").href
'https://example/foo//x'
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
The leading backslash should have the same behavior as if it were a proper /
. The input would be treated as a path-absolute URL (replacing the whole path from the base URL), or a scheme-relative URL (replacing all but the scheme from the base URL).
For example:
new URL("\\x", "https://example/foo/bar").href
-> "https://example/x"
new URL("\\\\x", "https://example/foo/bar").href
-> "https://x/"
What do you see instead?
The leading backslash is treated incorrectly. The effect seems to be as if the input were a path-relative-URL string -- the base URL's path, except for its last component, appears in the result. In the example:
> new URL("\\x", "https://example/foo/bar").href
'https://example/foo//x'
Additional information
The behavior of new URL
is documented as being defined by the WHATWG URL Standard. An input string like \x
, with a leading backslash, is never a "valid URL string" as defined in that standard... but the standard nevertheless defines what the URL
constructor should return for it.
Because the example input \x
is so short, it's not hard to walk through the URL parser as defined in the URL Standard and confirm what result the standard calls for. For the base URL of https://example/
, it goes from "scheme start state" to "no scheme state" to "relative state" to "relative slash state" to "path state", following exactly the same track as an input of /x
would do, except only that \x
emits a validation error. In the URL parser as defined by the URL Standard, a "validation error" does not affect the parser's result, so the resulting URL should be the same as for /x
.
As a different kind of check, Chrome (87.0.4280.88) gives the correct answer according to the spec. In the browser console:
> new URL("\\x", "https://example/foo/bar").href
"https://example/x"
So does Firefox (78.0):
» new URL("\\x", "https://example/foo/bar").href
← "https://example/x"