rust-url: url 2.5.8 diverges from the URL Standard in several places WPT hits
Generated from repros/rust-url-wpt-url-spec-gaps/README.md when the site was built at 7aa23e2.
What niso does
Section titled “What niso does”No workaround yet. niso’s URL implementation sits on the url crate (2.5.8 with idna 1.1.0, both the latest on
crates.io), and the WPT url/ tests fail wherever the crate differs from the current WHATWG URL Standard: about 770
IdnaTestV2 subtests and about 60 toascii ones (the ASCII-domain item), plus the opaque-path, file-URL, blob-origin
and /// cases below.
Expected vs actual
Section titled “Expected vs actual”Each case below is one expected-vs-actual line from cargo run (expected values are what WPT’s urltestdata.json and
setters_tests.json say, except the three xn-- domains, which come from the spec text and IdnaTestV2/toascii).
| Item | Input | Expected | Actual (url 2.5.8) |
|---|---|---|---|
| ASCII domain fallback | https://xn--ab-j1t/x |
https://xn--ab-j1t/x |
error: invalid international domain name |
| ASCII domain fallback | http://a.b.c.xn--pokxncvks |
http://a.b.c.xn--pokxncvks/ |
error: invalid international domain name |
| ASCII domain fallback | https://xn--/ |
https://xn--/ |
error: invalid international domain name |
| opaque path trailing space | non-special:opaque ?hi |
non-special:opaque %20?hi |
non-special:opaque ?hi |
| opaque path trailing space | sc:space ?query, search set to "" |
sc:space%20 |
sc:space |
| file host | /c:/foo/bar against file://host/path |
file://host/c:/foo/bar |
file:///c:/foo/bar |
| file empty segment | file:////foo |
file:////foo |
file:///foo |
| file drive letter | `file:///w | /m` | file:///w:/m |
| blob origin | blob:ftp://host/path |
null |
ftp://host |
| blob origin | blob:ws://example.org/ |
null |
ws://example.org |
scheme-relative /// |
///test against http://example.org/ |
http://test/ |
error: empty host |
The spec text behind the first rows is domain to ASCII: “If beStrict is false and domain is an ASCII string, then
set result to domain, lowercased” (whatwg/url#914), instead of failing when UTS46 ToASCII reports errors. ///test
fails in url (verified, not just seen in niso): the relative slash state stays in “special authority ignore
slashes” and only the host state rejects an empty buffer.
CARGO_TARGET_DIR=~/.capy/work/repro-target cargo runExit status 1 if any line differs, which it does for all eleven.
Upstream main
Section titled “Upstream main”All eleven lines reproduce on servo/rust-url main at 13b385b299238306d2601ddc1c0043afcd2f2046 (url 2.5.8, idna
1.1.0, run through a path dependency on the checkout). Open PRs already fix some, checked by running this repro on
each PR’s head:
| Item | Status |
|---|---|
| ASCII domain fallback | fixed by open #1170 (1dc6677b): all three domains parse |
file:////foo, file:///w|/m |
fixed by open #1166 (9907a302) |
///test |
not fixed by #1166; open issue #1164 |
opaque path trailing space, /c:/ against a host base, blob origin |
reproduce on main and both PRs |
Existing issue or PR
Section titled “Existing issue or PR”- ASCII domain fallback: https://github.com/servo/rust-url/pull/1170 (open, “Implement the URL Standard fallback for ASCII domains (whatwg/url#914)”). No separate issue found.
- Opaque path trailing spaces: none for the
%20encoding. Older, closed or merged work on the previous spec wording: https://github.com/servo/rust-url/pull/813 (merged), https://github.com/servo/rust-url/pull/848 (merged), https://github.com/servo/rust-url/issues/847 (closed). Related open: https://github.com/servo/rust-url/issues/1123 and https://github.com/servo/rust-url/issues/1176 (set_pathround-tripping). - File URLs: https://github.com/servo/rust-url/pull/1166 (open;
file:////fooandw|), https://github.com/servo/rust-url/issues/504 (open, joining a path onto afile://hostURL drops the host: the same host-preservation bug), https://github.com/servo/rust-url/issues/1126 (closed as completed, but only thefile://host/C:/parse form was reported; the base-host/c:/foo/barcase still reproduces). - Blob origin: none found. https://github.com/servo/rust-url/issues/1111 (open, custom schemes with non-opaque origins) is adjacent, not the same.
///relative: https://github.com/servo/rust-url/issues/1164 (open). Closed PRs https://github.com/servo/rust-url/pull/1134 and https://github.com/servo/rust-url/pull/1136 tried to fix it.
Issue text
Section titled “Issue text”Only the three items with no existing issue or PR need new text; ASCII domains, file:////foo/w| and /// have PRs
or issues above.
Title: Opaque paths with trailing spaces, and blob origins, differ from the URL Standard
Body:
Two divergences found by running WPT urltestdata.json / setters_tests.json against url 2.5.8 (also on main
13b385b299238306d2601ddc1c0043afcd2f2046):
// Cargo.toml: url = "2.5.8"fn main() { // WPT: "non-special:opaque ?hi" -> "non-special:opaque %20?hi" assert_eq!(url::Url::parse("non-special:opaque ?hi").unwrap().as_str(), "non-special:opaque %20?hi"); // actual: "non-special:opaque ?hi" // WPT: origin of "blob:ftp://host/path" is opaque ("null") assert_eq!(url::quirks::origin(&url::Url::parse("blob:ftp://host/path").unwrap()), "null"); // actual: "ftp://host"}Also WPT’s setters: setting search to "" on sc:space ?query gives sc:space%20 (url gives sc:space).
The URL Standard percent-encodes the last trailing space of an opaque path when the path is followed by a query or
fragment, and the blob URL origin is the origin of the inner URL only for http and https.