Skip to content

Commit 282a0d0

Browse files
committed
Make sure special urls always have a non empty path.
1 parent 0f3b6bb commit 282a0d0

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
@@ -1043,28 +1043,28 @@ impl<'a> Parser<'a> {
10431043
input: Input<'i>,
10441044
) -> Input<'i> {
10451045
let path_start = self.serialization.len();
1046-
let (maybe_c, remaining) = input.split_first();
1046+
let (maybe_c, _) = input.split_first();
10471047
// If url is special, then:
10481048
if scheme_type.is_special() {
1049+
// A special URL always has a non-empty path.
1050+
if maybe_c != Some('/') {
1051+
self.serialization.push('/');
1052+
}
10491053
if let Some(c) = maybe_c {
10501054
if c == '\\' {
10511055
// If c is U+005C (\), validation error.
10521056
self.log_violation(SyntaxViolation::Backslash);
10531057
}
10541058
// Set state to path state.
10551059
return self.parse_path(scheme_type, has_host, path_start, input);
1056-
} else {
1057-
// A special URL always has a non-empty path.
1058-
self.serialization.push('/');
10591060
}
1060-
} else if maybe_c == Some('?') {
1061+
} else if maybe_c == Some('?') || maybe_c == Some('#') {
10611062
// Otherwise, if state override is not given and c is U+003F (?),
10621063
// set url’s query to the empty string and state to query state.
1063-
return self.parse_query_2(scheme_type, remaining);
1064-
} else if maybe_c == Some('#') {
10651064
// Otherwise, if state override is not given and c is U+0023 (#),
10661065
// set url’s fragment to the empty string and state to fragment state.
1067-
return self.parse_fragment_2(remaining);
1066+
// The query and path states will be handled by the caller.
1067+
return input;
10681068
}
10691069
// Otherwise, if c is not the EOF code point:
10701070
self.parse_path(scheme_type, has_host, path_start, input)
@@ -1184,7 +1184,12 @@ impl<'a> Parser<'a> {
11841184
}
11851185
}
11861186

1187-
match &self.serialization[segment_start..] {
1187+
let to_match = if ends_with_slash {
1188+
&self.serialization[segment_start..self.serialization.len() - 1]
1189+
} else {
1190+
&self.serialization[segment_start..self.serialization.len()]
1191+
};
1192+
match to_match {
11881193
// If buffer is a double-dot path segment, shorten url’s path,
11891194
// 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.
11901195
".." | "%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)