Skip to content

Commit

Permalink
Avoid reparse issues with non-special URLs
Browse files Browse the repository at this point in the history
This is a willfull violation of the URL specification for serialization.
It retains spec-compliance for parsing, it aligns with the behavior
of Microsoft Edge, and it "fixes" an acknowledged specification bug.

See whatwg/url#415

Fixes #397
  • Loading branch information
notriddle committed Dec 11, 2018
1 parent 3851a94 commit a9c7af5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1035,12 +1035,21 @@ impl Url {
/// # run().unwrap();
/// ```
pub fn path(&self) -> &str {
match (self.query_start, self.fragment_start) {
let path = match (self.query_start, self.fragment_start) {
(None, None) => self.slice(self.path_start..),
(Some(next_component_start), _) |
(None, Some(next_component_start)) => {
self.slice(self.path_start..next_component_start)
}
};
// Disambiguating a path that starts with "//" from a URL with an authority may require
// the serializer to insert a disambiguating marker to the start of the path.
// When deserializing, "/./" is supposed to be reduced to "/", so avoid exposing it to
// the application.
if path.len() >= 3 && &path[..3] == "/./" {
&path[2..]
} else {
path
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,17 @@ impl<'a> Parser<'a> {
}
}
if ends_with_slash {
// This is a willfull violation of the URL specification for serialization.
//
// It aligns with the behaviour of Microsoft Edge,
// it does not affect the result of parsing (that's still compliant),
// and it's necessary to make URL reparsing idempotent.
//
// See the specification bug at https://github.com/whatwg/url/issues/415
if !*has_host && &self.serialization[path_start..] == "/" {
self.serialization.push('.');
self.serialization.push('/');
}
self.serialization.push('/')
}
}
Expand Down
15 changes: 15 additions & 0 deletions tests/urltestdata.json
Original file line number Diff line number Diff line change
Expand Up @@ -6144,5 +6144,20 @@
"pathname": "/test",
"search": "?a",
"hash": "#bc"
},
"Found by fuzzing",
{
"input": "a:/a/..//a",
"base": "about:blank",
"href": "a:/.//a",
"protocol": "a:",
"username": "",
"password": "",
"host": "",
"hostname": "",
"port": "",
"pathname": "//a",
"search": "",
"hash": ""
}
]

0 comments on commit a9c7af5

Please sign in to comment.