Skip to content

Commit e4a27e5

Browse files
committed
Make sure special urls always have a non empty path.
1 parent bca9ddd commit e4a27e5

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

src/parser.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,28 +1025,28 @@ impl<'a> Parser<'a> {
10251025
input: Input<'i>,
10261026
) -> Input<'i> {
10271027
let path_start = self.serialization.len();
1028-
let (maybe_c, remaining) = input.split_first();
1028+
let (maybe_c, _) = input.split_first();
10291029
// If url is special, then:
10301030
if scheme_type.is_special() {
1031+
// A special URL always has a non-empty path.
1032+
if maybe_c != Some('/') {
1033+
self.serialization.push('/');
1034+
}
10311035
if let Some(c) = maybe_c {
10321036
if c == '\\' {
10331037
// If c is U+005C (\), validation error.
10341038
self.log_violation(SyntaxViolation::Backslash);
10351039
}
10361040
// Set state to path state.
10371041
return self.parse_path(scheme_type, has_host, path_start, input);
1038-
} else {
1039-
// A special URL always has a non-empty path.
1040-
self.serialization.push('/');
10411042
}
1042-
} else if maybe_c == Some('?') {
1043+
} else if maybe_c == Some('?') || maybe_c == Some('#') {
10431044
// Otherwise, if state override is not given and c is U+003F (?),
10441045
// set url’s query to the empty string and state to query state.
1045-
return self.parse_query_2(scheme_type, remaining);
1046-
} else if maybe_c == Some('#') {
10471046
// Otherwise, if state override is not given and c is U+0023 (#),
10481047
// set url’s fragment to the empty string and state to fragment state.
1049-
return self.parse_fragment_2(remaining);
1048+
// The query and path states will be handled by the caller.
1049+
return input;
10501050
}
10511051
// Otherwise, if c is not the EOF code point:
10521052
self.parse_path(scheme_type, has_host, path_start, input)
@@ -1166,7 +1166,12 @@ impl<'a> Parser<'a> {
11661166
}
11671167
}
11681168

1169-
match &self.serialization[segment_start..] {
1169+
let to_match = if ends_with_slash {
1170+
&self.serialization[segment_start..self.serialization.len() - 1]
1171+
} else {
1172+
&self.serialization[segment_start..self.serialization.len()]
1173+
};
1174+
match to_match {
11701175
// If buffer is a double-dot path segment, shorten url’s path,
11711176
// and then if neither c is U+002F (/), nor url is special and c is U+005C (\), append the empty string to url’s path.
11721177
".." | "%2e%2e" | "%2e%2E" | "%2E%2e" | "%2E%2E" | "%2e." | "%2E." | ".%2e"

src/quirks.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,10 @@ pub fn pathname(url: &Url) -> &str {
184184
/// Setter for https://url.spec.whatwg.org/#dom-url-pathname
185185
pub fn set_pathname(url: &mut Url, new_pathname: &str) {
186186
if !url.cannot_be_a_base() && !new_pathname.is_empty() {
187-
if !SchemeType::from(url.scheme()).is_special() || Some('/') == new_pathname.chars().nth(0)
187+
if !SchemeType::from(url.scheme()).is_special()
188+
|| Some('/') == new_pathname.chars().nth(0)
189+
// \\ is a segment delimiter for 'special' URLs"
190+
|| Some('\\') == new_pathname.chars().nth(0)
188191
{
189192
url.set_path(new_pathname)
190193
} else {

0 commit comments

Comments
 (0)