Skip to content

Commit 09311b0

Browse files
committed
refactor gix-url
- put more standard-derives on `ArgumentSafety` to allow more convenient usage. - remove `path_as_argument()` method as it wasn't adding anything. This allowed the `ArgumentSafety` wrapper to be simpler. - turn assertion comments into messages.
1 parent 03fb64a commit 09311b0

File tree

2 files changed

+21
-41
lines changed

2 files changed

+21
-41
lines changed

gix-url/src/lib.rs

+6-23
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,14 @@ pub fn expand_path(user: Option<&expand_path::ForUser>, path: &BStr) -> Result<P
6666
///
6767
/// This type only expresses known *syntactic* risk. It does not cover other risks, such as passing a personal access
6868
/// token as a username rather than a password in an application that logs usernames.
69-
#[derive(Debug, PartialEq)]
70-
pub enum ArgumentSafety<T> {
69+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
70+
pub enum ArgumentSafety<'a> {
7171
/// May be safe. There is nothing to pass, so there is nothing dangerous.
7272
Absent,
7373
/// May be safe. The argument does not begin with a `-` and so will not be confused as an option.
74-
Usable(T),
74+
Usable(&'a str),
7575
/// Dangerous! Begins with `-` and could be treated as an option. Use the value in error messages only.
76-
Dangerous(T),
76+
Dangerous(&'a str),
7777
}
7878

7979
/// A URL with support for specialized git related capabilities.
@@ -201,7 +201,7 @@ impl Url {
201201
///
202202
/// Use this method instead of [Self::user()] if the host is going to be passed to a command-line application.
203203
/// If the unsafe and absent cases need not be distinguished, [Self::user_argument_safe()] may also be used.
204-
pub fn user_as_argument(&self) -> ArgumentSafety<&str> {
204+
pub fn user_as_argument(&self) -> ArgumentSafety<'_> {
205205
match self.user() {
206206
Some(user) if looks_like_command_line_option(user.as_bytes()) => ArgumentSafety::Dangerous(user),
207207
Some(user) => ArgumentSafety::Usable(user),
@@ -243,7 +243,7 @@ impl Url {
243243
///
244244
/// Use this method instead of [Self::host()] if the host is going to be passed to a command-line application.
245245
/// If the unsafe and absent cases need not be distinguished, [Self::host_argument_safe()] may also be used.
246-
pub fn host_as_argument(&self) -> ArgumentSafety<&str> {
246+
pub fn host_as_argument(&self) -> ArgumentSafety<'_> {
247247
match self.host() {
248248
Some(host) if looks_like_command_line_option(host.as_bytes()) => ArgumentSafety::Dangerous(host),
249249
Some(host) => ArgumentSafety::Usable(host),
@@ -263,28 +263,11 @@ impl Url {
263263
}
264264
}
265265

266-
/// Classify the path of this URL by whether it is safe to pass as a command-line argument.
267-
/// Note that it always begins with a slash, which is ignored for this classification.
268-
///
269-
/// Use this method or [Self::path_argument_safe()] instead of [Self::path] if the host is going to be
270-
/// passed to a command-line application, unless it is certain that the leading `/` will always be included.
271-
///
272-
/// This method never returns an [ArgumentSafety::Absent].
273-
pub fn path_as_argument(&self) -> ArgumentSafety<&BStr> {
274-
match self.path_argument_safe() {
275-
Some(path) => ArgumentSafety::Usable(path),
276-
None => ArgumentSafety::Dangerous(self.path.as_ref()),
277-
}
278-
}
279-
280266
/// Return the path of this URL *if* it can't be mistaken for a command-line argument.
281267
/// Note that it always begins with a slash, which is ignored for this comparison.
282268
///
283269
/// Use this method instead of accessing [Self::path] directly if the path is going to be passed to a
284270
/// command-line application, unless it is certain that the leading `/` will always be included.
285-
///
286-
/// The result of this method is unambiguous because [Self::path] is not an option type, but
287-
/// [Self::path_as_argument()] may also safely be used.
288271
pub fn path_argument_safe(&self) -> Option<&BStr> {
289272
self.path
290273
.get(1..)

gix-url/tests/access/mod.rs

+15-18
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,13 @@ fn user_argument_safety() -> crate::Result {
6060

6161
assert_eq!(url.user(), Some("-Fconfigfile"));
6262
assert_eq!(url.user_as_argument(), ArgumentSafety::Dangerous("-Fconfigfile"));
63-
assert_eq!(url.user_argument_safe(), None); // An unsafe username is blocked.
63+
assert_eq!(url.user_argument_safe(), None, "An unsafe username is blocked.");
6464

6565
assert_eq!(url.host(), Some("foo"));
6666
assert_eq!(url.host_as_argument(), ArgumentSafety::Usable("foo"));
6767
assert_eq!(url.host_argument_safe(), Some("foo"));
6868

6969
assert_eq!(url.path, "/bar");
70-
assert_eq!(url.path_as_argument(), ArgumentSafety::Usable("/bar".into()));
7170
assert_eq!(url.path_argument_safe(), Some("/bar".into()));
7271

7372
Ok(())
@@ -79,17 +78,20 @@ fn host_argument_safety() -> crate::Result {
7978

8079
assert_eq!(url.user(), None);
8180
assert_eq!(url.user_as_argument(), ArgumentSafety::Absent);
82-
assert_eq!(url.user_argument_safe(), None); // As there is no user. See all_argument_safe_valid().
81+
assert_eq!(
82+
url.user_argument_safe(),
83+
None,
84+
"As there is no user. See all_argument_safe_valid()"
85+
);
8386

8487
assert_eq!(url.host(), Some("-oProxyCommand=open$IFS-aCalculator"));
8588
assert_eq!(
8689
url.host_as_argument(),
8790
ArgumentSafety::Dangerous("-oProxyCommand=open$IFS-aCalculator")
8891
);
89-
assert_eq!(url.host_argument_safe(), None); // An unsafe host string is blocked.
92+
assert_eq!(url.host_argument_safe(), None, "An unsafe host string is blocked");
9093

9194
assert_eq!(url.path, "/foo");
92-
assert_eq!(url.path_as_argument(), ArgumentSafety::Usable("/foo".into()));
9395
assert_eq!(url.path_argument_safe(), Some("/foo".into()));
9496

9597
Ok(())
@@ -101,18 +103,18 @@ fn path_argument_safety() -> crate::Result {
101103

102104
assert_eq!(url.user(), None);
103105
assert_eq!(url.user_as_argument(), ArgumentSafety::Absent);
104-
assert_eq!(url.user_argument_safe(), None); // As there is no user. See all_argument_safe_valid().
106+
assert_eq!(
107+
url.user_argument_safe(),
108+
None,
109+
"As there is no user. See all_argument_safe_valid()"
110+
);
105111

106112
assert_eq!(url.host(), Some("foo"));
107113
assert_eq!(url.host_as_argument(), ArgumentSafety::Usable("foo"));
108114
assert_eq!(url.host_argument_safe(), Some("foo"));
109115

110116
assert_eq!(url.path, "/-oProxyCommand=open$IFS-aCalculator");
111-
assert_eq!(
112-
url.path_as_argument(),
113-
ArgumentSafety::Dangerous("/-oProxyCommand=open$IFS-aCalculator".into())
114-
);
115-
assert_eq!(url.path_argument_safe(), None); // An unsafe path is blocked.
117+
assert_eq!(url.path_argument_safe(), None, "An unsafe path is blocked");
116118

117119
Ok(())
118120
}
@@ -130,7 +132,6 @@ fn all_argument_safety_safe() -> crate::Result {
130132
assert_eq!(url.host_argument_safe(), Some("example.com"));
131133

132134
assert_eq!(url.path, "/path/to/file");
133-
assert_eq!(url.path_as_argument(), ArgumentSafety::Usable("/path/to/file".into()));
134135
assert_eq!(url.path_argument_safe(), Some("/path/to/file".into()));
135136

136137
Ok(())
@@ -150,14 +151,10 @@ fn all_argument_safety_not_safe() -> crate::Result {
150151
url.host_as_argument(),
151152
ArgumentSafety::Dangerous("-oProxyCommand=open$IFS-aCalculator")
152153
);
153-
assert_eq!(url.host_argument_safe(), None); // An unsafe host string is blocked.
154+
assert_eq!(url.host_argument_safe(), None, "An unsafe host string is blocked");
154155

155156
assert_eq!(url.path, "/-oProxyCommand=open$IFS-aCalculator");
156-
assert_eq!(
157-
url.path_as_argument(),
158-
ArgumentSafety::Dangerous("/-oProxyCommand=open$IFS-aCalculator".into())
159-
);
160-
assert_eq!(url.path_argument_safe(), None); // An unsafe path is blocked.
157+
assert_eq!(url.path_argument_safe(), None, "An unsafe path is blocked");
161158

162159
Ok(())
163160
}

0 commit comments

Comments
 (0)