path normalization fixed for relative paths

This commit is contained in:
Janis 2023-04-03 17:01:11 +02:00
parent f2885b7e00
commit d4f62371f8

View file

@ -38,12 +38,24 @@ pub trait Path: AsRef<[u8]> {
Segment::NoOp | Segment::CurrentDir => {} Segment::NoOp | Segment::CurrentDir => {}
Segment::Root | Segment::File(_) => segments.push_back(segment), Segment::Root | Segment::File(_) => segments.push_back(segment),
Segment::ParentDir => { Segment::ParentDir => {
if segments.back() != Some(&Segment::Root) { match segments.back() {
// parent of root is still root, so do nothing
Some(&Segment::Root) => {}
// relative path has to contain parentdir going up past
// the current dir if segments already contain a
// parentdir we know we must be in a relative path above
// the current dir
None | Some(&Segment::ParentDir) => {
segments.push_back(segment);
}
// some path exists, pop up to parent
_ => {
segments.pop_back(); segments.pop_back();
} }
} }
} }
} }
}
NormalizedPath { segments } NormalizedPath { segments }
} }
@ -168,6 +180,31 @@ mod tests {
assert_eq!(iter.next(), Some(&b"some.file"[..])); assert_eq!(iter.next(), Some(&b"some.file"[..]));
assert_eq!(iter.next(), None); assert_eq!(iter.next(), None);
} }
#[test]
fn test_normalizing() {
// normalizes to "/path"
let path = b"///../../some/../path".normalize();
let mut iter = path.into_iter();
assert_eq!(iter.next(), Some(Segment::Root));
assert_eq!(iter.next(), Some(Segment::File(&b"path"[..])));
assert_eq!(iter.next(), None);
// normalizes to "../../path"
let path = b"../../some/../path".normalize();
let mut iter = path.into_iter();
assert_eq!(iter.next(), Some(Segment::ParentDir));
assert_eq!(iter.next(), Some(Segment::ParentDir));
assert_eq!(iter.next(), Some(Segment::File(&b"path"[..])));
assert_eq!(iter.next(), None);
// normalizes to "../.."
let path = b".././../some/../path/..".normalize();
let mut iter = path.into_iter();
assert_eq!(iter.next(), Some(Segment::ParentDir));
assert_eq!(iter.next(), Some(Segment::ParentDir));
assert_eq!(iter.next(), None);
}
} }
#[cfg(test)] #[cfg(test)]