Skip to content

Commit 3ec40ae

Browse files
committed
Check that paths are not absolute
1 parent e31de68 commit 3ec40ae

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

Diff for: gix-path/src/relative_path.rs

+50
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ impl RelativePath {
3838
#[derive(Debug, thiserror::Error)]
3939
#[allow(missing_docs)]
4040
pub enum Error {
41+
#[error("A RelativePath is not allowed to be absolute")]
42+
IsAbsolute,
4143
#[error(transparent)]
4244
ContainsInvalidComponent(#[from] gix_validate::path::component::Error),
4345
#[error(transparent)]
@@ -51,6 +53,11 @@ impl<'a> TryFrom<&'a str> for &'a RelativePath {
5153
use std::path::Path;
5254

5355
let path: &std::path::Path = Path::new(value);
56+
57+
if path.is_absolute() {
58+
return Err(Error::IsAbsolute);
59+
}
60+
5461
let options: Options = Default::default();
5562

5663
for component in path.components() {
@@ -68,6 +75,11 @@ impl<'a> TryFrom<&'a BStr> for &'a RelativePath {
6875

6976
fn try_from(value: &'a BStr) -> Result<Self, Self::Error> {
7077
let path: &std::path::Path = &try_from_bstr(value)?;
78+
79+
if path.is_absolute() {
80+
return Err(Error::IsAbsolute);
81+
}
82+
7183
let options: Options = Default::default();
7284

7385
for component in path.components() {
@@ -87,6 +99,10 @@ impl<'a, const N: usize> TryFrom<&'a [u8; N]> for &'a RelativePath {
8799
fn try_from(value: &'a [u8; N]) -> Result<Self, Self::Error> {
88100
let path: &std::path::Path = try_from_byte_slice(value)?;
89101

102+
if path.is_absolute() {
103+
return Err(Error::IsAbsolute);
104+
}
105+
90106
let options: Options = Default::default();
91107

92108
for component in path.components() {
@@ -105,6 +121,10 @@ impl<'a> TryFrom<&'a BString> for &'a RelativePath {
105121
fn try_from(value: &'a BString) -> Result<Self, Self::Error> {
106122
let path: &std::path::Path = &try_from_bstr(value.as_bstr())?;
107123

124+
if path.is_absolute() {
125+
return Err(Error::IsAbsolute);
126+
}
127+
108128
let options: Options = Default::default();
109129

110130
for component in path.components() {
@@ -131,3 +151,33 @@ impl AsRef<[u8]> for RelativePath {
131151
self.inner.as_bytes()
132152
}
133153
}
154+
155+
#[cfg(test)]
156+
mod tests {
157+
use super::*;
158+
159+
#[test]
160+
fn absolute_paths_return_err() {
161+
let path_str: &str = "/refs/heads";
162+
let path_bstr: &BStr = path_str.into();
163+
let path_u8: &[u8; 11] = b"/refs/heads";
164+
let path_bstring: BString = "/refs/heads".into();
165+
166+
assert!(matches!(
167+
TryInto::<&RelativePath>::try_into(path_str),
168+
Err(Error::IsAbsolute)
169+
));
170+
assert!(matches!(
171+
TryInto::<&RelativePath>::try_into(path_bstr),
172+
Err(Error::IsAbsolute)
173+
));
174+
assert!(matches!(
175+
TryInto::<&RelativePath>::try_into(path_u8),
176+
Err(Error::IsAbsolute)
177+
));
178+
assert!(matches!(
179+
TryInto::<&RelativePath>::try_into(&path_bstring),
180+
Err(Error::IsAbsolute)
181+
));
182+
}
183+
}

Diff for: gix-ref/src/store/file/overlay_iter.rs

-6
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,6 @@ impl<'a> IterInfo<'a> {
296296

297297
fn from_prefix(base: &'a Path, prefix: &'a RelativePath, precompose_unicode: bool) -> std::io::Result<Self> {
298298
let prefix_path = gix_path::from_bstr(prefix);
299-
if prefix_path.is_absolute() {
300-
return Err(std::io::Error::new(
301-
std::io::ErrorKind::InvalidInput,
302-
"prefix must be a relative path, like 'refs/heads/'",
303-
));
304-
}
305299
let iter_root = base.join(&prefix_path);
306300
if prefix.ends_with(b"/") {
307301
Ok(IterInfo::BaseAndIterRoot {

0 commit comments

Comments
 (0)