Summary
Calling set_host(Some("localhost")) on a file:/// URL produces file://localhost/..., but re-parsing that serialization strips localhost per the WHATWG URL spec (which normalizes file://localhost/ to file:///). This means the URL produced by set_host does not roundtrip through Url::parse.
Reproduction
use url::Url;
fn main() {
let mut url = Url::parse("file:///tmp/test").unwrap();
url.set_host(Some("localhost")).unwrap();
let modified = url.as_str().to_string();
println!("After set_host: {:?}", modified);
// After set_host: "file://localhost/tmp/test"
let reparsed = Url::parse(&modified).unwrap();
println!("Reparsed: {:?}", reparsed.as_str());
// Reparsed: "file:///tmp/test"
assert_eq!(modified, reparsed.as_str()); // FAILS
}
Analysis
Per the WHATWG URL standard, file://localhost/ is normalized to file:/// during parsing. The set_host method should apply the same normalization — when setting the host to "localhost" on a file:// URL, it should either:
- Normalize it away (set host to empty/None), or
- Serialize it without
localhost so the output roundtrips
Currently set_host stores localhost literally, producing a serialization that the parser will normalize differently on re-parse.
Found by
This bug was found by fuzzing with the fuzz_url_setters target (see #1100).
Summary
Calling
set_host(Some("localhost"))on afile:///URL producesfile://localhost/..., but re-parsing that serialization stripslocalhostper the WHATWG URL spec (which normalizesfile://localhost/tofile:///). This means the URL produced byset_hostdoes not roundtrip throughUrl::parse.Reproduction
Analysis
Per the WHATWG URL standard,
file://localhost/is normalized tofile:///during parsing. Theset_hostmethod should apply the same normalization — when setting the host to"localhost"on afile://URL, it should either:localhostso the output roundtripsCurrently
set_hoststoreslocalhostliterally, producing a serialization that the parser will normalize differently on re-parse.Found by
This bug was found by fuzzing with the
fuzz_url_setterstarget (see #1100).