Skip to content

Commit

Permalink
fix: make file:// url parsing with full backslashed path more robust …
Browse files Browse the repository at this point in the history
…on windows. (GitoxideLabs#1063)
  • Loading branch information
Byron committed Oct 13, 2023
1 parent 117357e commit 562b0c9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
5 changes: 4 additions & 1 deletion gix-url/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ pub(crate) fn file_url(input: &BStr, protocol_colon: usize) -> Result<crate::Url
let input = input_to_utf8(input, UrlKind::Url)?;
let input_after_protocol = &input[protocol_colon + "://".len()..];

let Some(first_slash) = input_after_protocol.find('/') else {
let Some(first_slash) = input_after_protocol
.find('/')
.or_else(|| cfg!(windows).then(|| input_after_protocol.find('\\')).flatten())
else {
return Err(Error::MissingRepositoryPath {
url: input.to_owned().into(),
kind: UrlKind::Url,
Expand Down
20 changes: 18 additions & 2 deletions gix-url/tests/parse/file.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use assert_matches::assert_matches;
use bstr::ByteSlice;
use gix_url::Scheme;

Expand Down Expand Up @@ -93,11 +92,19 @@ fn no_relative_paths_if_protocol() -> crate::Result {
assert_url_roundtrip("file://../", url(Scheme::File, None, "..", None, b"/"))?;
assert_url_roundtrip("file://./", url(Scheme::File, None, ".", None, b"/"))?;
assert_url_roundtrip("file://a/", url(Scheme::File, None, "a", None, b"/"))?;
assert_matches!(
if cfg!(windows) {
assert_eq!(
gix_url::parse("file://.\\".into())?,
url(Scheme::File, None, ".", None, b"\\"),
"we are just as none-sensical as git here due to special handling."
);
} else {
assert_matches::assert_matches!(
gix_url::parse("file://.\\".into()),
Err(gix_url::parse::Error::MissingRepositoryPath { .. }),
"DEVIATION: on windows, this parses with git into something nonesensical Diag: url=file://./ Diag: protocol=file Diag: hostandport=./ Diag: path=//./"
);
}
Ok(())
}

Expand All @@ -122,6 +129,15 @@ mod windows {
use crate::parse::{assert_url, assert_url_roundtrip, url, url_alternate};
use gix_url::Scheme;

#[test]
fn reproduce_1063() -> crate::Result {
let input = "C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\tmp.vIa4tyjv17";
let url_input = "file://C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\tmp.vIa4tyjv17";
assert_url(url_input, url(Scheme::File, None, None, None, input.as_bytes()))?;
assert_url(input, url_alternate(Scheme::File, None, None, None, input.as_bytes()))?;
Ok(())
}

#[test]
fn url_from_absolute_path() -> crate::Result {
assert_url(
Expand Down
1 change: 0 additions & 1 deletion gix-url/tests/parse/invalid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ fn empty_input() {
fn file_missing_host_path_separator() {
assert_matches!(parse("file://.."), Err(MissingRepositoryPath { .. }));
assert_matches!(parse("file://."), Err(MissingRepositoryPath { .. }));
assert_matches!(parse("file://.\\"), Err(MissingRepositoryPath { .. }));
assert_matches!(parse("file://a"), Err(MissingRepositoryPath { .. }));
}

Expand Down

0 comments on commit 562b0c9

Please sign in to comment.