Skip to content

Commit 0e579a0

Browse files
committed
Merge branch 'url-fix'
2 parents e3c5a0f + 3c060cb commit 0e579a0

File tree

4 files changed

+44
-23
lines changed

4 files changed

+44
-23
lines changed

gix-url/src/impls.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,17 @@ impl<'a> TryFrom<std::borrow::Cow<'a, BStr>> for Url {
7878
Self::try_from(&*value)
7979
}
8080
}
81+
82+
impl std::fmt::Display for Url {
83+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84+
let mut storage;
85+
let to_print = if self.password.is_some() {
86+
storage = self.clone();
87+
storage.password = Some("<redacted>".into());
88+
&storage
89+
} else {
90+
self
91+
};
92+
to_print.to_bstring().fmt(f)
93+
}
94+
}

gix-url/src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,17 @@ pub fn expand_path(user: Option<&expand_path::ForUser>, path: &BStr) -> Result<P
5555

5656
/// A URL with support for specialized git related capabilities.
5757
///
58-
/// Additionally there is support for [deserialization](Url::from_bytes()) and serialization
59-
/// (_see the [`std::fmt::Display::fmt()`] implementation_).
58+
/// Additionally there is support for [deserialization](Url::from_bytes()) and [serialization](Url::to_bstring()).
6059
///
6160
/// # Security Warning
6261
///
63-
/// URLs may contain passwords and we serialize them when [formatting](std::fmt::Display) or
64-
/// [serializing losslessly](Url::to_bstring()).
62+
/// URLs may contain passwords and using standard [formatting](std::fmt::Display) will redact
63+
/// such password, whereas [lossless serialization](Url::to_bstring()) will contain all parts of the
64+
/// URL.
65+
/// **Beware that some URls still print secrets if they use them outside of the designated password fields.**
66+
///
67+
/// Also note that URLs that fail to parse are typically stored in [the resulting error](parse::Error) type
68+
/// and printed in full using its display implementation.
6569
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
6670
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6771
pub struct Url {

gix-url/tests/access/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,23 @@ fn path_argument_safe() -> crate::Result {
7171
assert_eq!(url.path_argument_safe(), None);
7272
Ok(())
7373
}
74+
75+
#[test]
76+
fn display() {
77+
fn compare(input: &str, expected: &str, message: &str) {
78+
let url = gix_url::parse(input.into()).expect("input is valid url");
79+
assert_eq!(format!("{url}"), expected, "{message}");
80+
}
81+
82+
compare(
83+
"ssh://foo/-oProxyCommand=open$IFS-aCalculator",
84+
"ssh://foo/-oProxyCommand=open$IFS-aCalculator",
85+
"it round-trips with sane unicode and without password",
86+
);
87+
compare("/path/to/repo", "/path/to/repo", "same goes for simple paths");
88+
compare(
89+
"https://user:password@host/path",
90+
"https://user:<redacted>@host/path",
91+
"it visibly redacts passwords though",
92+
);
93+
}

gix-url/tests/fuzzed.rs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,11 @@ use std::{path::Path, time::Duration};
22

33
use bstr::ByteSlice;
44

5-
#[test]
6-
#[cfg_attr(debug_assertions, ignore = "fails due to integer overflow")]
7-
fn abort_unfixed_in_debug_mode() {
8-
for name in ["very-long-abort2", "very-long-abort"] {
9-
let base = Path::new("tests").join("fixtures").join("fuzzed");
10-
let location = base.join(Path::new(name).with_extension("url"));
11-
let url = std::fs::read(&location).unwrap();
12-
let start = std::time::Instant::now();
13-
dbg!(name);
14-
gix_url::parse(url.as_bstr()).ok();
15-
assert!(
16-
start.elapsed() < Duration::from_millis(100),
17-
"URL at '{}' parsed too slowly, took {:.00}s",
18-
location.display(),
19-
start.elapsed().as_secs_f32()
20-
);
21-
}
22-
}
23-
245
#[test]
256
fn fuzzed() {
267
for name in [
8+
"very-long-abort2",
9+
"very-long-abort",
2710
"very-long6",
2811
"very-long5",
2912
"very-long4",

0 commit comments

Comments
 (0)