diff --git a/url/src/parser.rs b/url/src/parser.rs index 6ccfa9b46..dbfb92c63 100644 --- a/url/src/parser.rs +++ b/url/src/parser.rs @@ -1323,7 +1323,8 @@ impl Parser<'_> { _ => { // If url’s scheme is "file", url’s path is empty, and buffer is a Windows drive letter, then if scheme_type.is_file() - && segment_start == path_start + 1 + && segment_start + == Parser::file_first_segment_start(&self.serialization, path_start) && is_windows_drive_letter(segment_before_slash) { // Replace the second code point in buffer with U+003A (:). @@ -1361,6 +1362,16 @@ impl Parser<'_> { input } + /// The offset at which `path[0]` of a `file:` URL begins. + /// + /// While a hostless `file:` URL is being parsed the serialization carries a + /// run of slashes at `path_start` rather than a single one, so the first + /// segment does not always begin at `path_start + 1`. + fn file_first_segment_start(serialization: &str, path_start: usize) -> usize { + let path = &serialization[path_start..]; + path_start + (path.len() - path.trim_start_matches('/').len()) + } + fn last_slash_can_be_removed(serialization: &str, path_start: usize) -> bool { let url_before_segment = &serialization[..serialization.len() - 1]; if let Some(segment_before_start) = url_before_segment.rfind('/') { diff --git a/url/tests/expected_failures.txt b/url/tests/expected_failures.txt index 314adad59..b5d818ee5 100644 --- a/url/tests/expected_failures.txt +++ b/url/tests/expected_failures.txt @@ -42,7 +42,6 @@ set pathname to set pathname to set pathname to

-