Skip to content

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.

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.

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.

Terminal window
CARGO_TARGET_DIR=~/.capy/work/repro-target cargo run

Exit status 1 if any line differs, which it does for all eleven.

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

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.