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 @@
-