@@ -177,18 +177,32 @@ fn parse_file_url(input: &BStr, protocol_colon: usize) -> Result<crate::Url, Err
177
177
178
178
// We can not use the url crate to parse host and path because it special cases Windows
179
179
// driver letters. With the url crate an input of `file://x:/path/to/git` is parsed as empty
180
- // host and with `x:/path/to/git` as path. This behavior is wrong for Git which parses the
181
- // `x:` as the host.
182
- // TODO: this behavior is most likely different on Windows
183
- let host = if first_slash == 0 {
184
- // file:///path/to/git
180
+ // host and with `x:/path/to/git` as path. This behavior is wrong for Git which only follows
181
+ // that rule on Windows and parses `x:` as host on Unix platforms. Additionally the url crate
182
+ // does not account for Windows special UNC path support.
183
+
184
+ // TODO: implement UNC path special case
185
+ let windows_special_path = if cfg ! ( windows) {
186
+ // parse `file://x:/path/to/git` as explained above
187
+ if input_after_protocol. chars ( ) . nth ( 1 ) == Some ( ':' ) {
188
+ Some ( input_after_protocol)
189
+ } else {
190
+ None
191
+ }
192
+ } else {
193
+ None
194
+ } ;
195
+
196
+ let host = if windows_special_path. is_some ( ) || first_slash == 0 {
197
+ // `file:///path/to/git` or a windows special case was triggered
185
198
None
186
199
} else {
187
- // file://host/path/to/git
200
+ // ` file://host/path/to/git`
188
201
Some ( & input_after_protocol[ ..first_slash] )
189
202
} ;
190
- // path includes the slash character
191
- let path = & input_after_protocol[ first_slash..] ;
203
+
204
+ // default behavior on Unix platforms and if no Windows special case was triggered
205
+ let path = windows_special_path. unwrap_or ( & input_after_protocol[ first_slash..] ) ;
192
206
193
207
Ok ( crate :: Url {
194
208
serialize_alternative_form : false ,
0 commit comments