Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/core/src/archiver/parent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl Parent {
loop {
match p_nodes.get(*idx) {
None => break None,
Some(p_node) => match p_node.name().as_os_str().cmp(name) {
Some(p_node) => match (*p_node.name()).cmp(name) {
Comment thread
aawsome marked this conversation as resolved.
Ordering::Less => *idx += 1,
Ordering::Equal => {
break Some(p_node);
Expand Down
10 changes: 7 additions & 3 deletions crates/core/src/archiver/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{

/// `TreeIterator` turns an Iterator yielding items with paths and Nodes into an
/// Iterator which ensures that all subdirectories are visited and closed.
/// The resulting Iterator yielss a `TreeType` which either contains the original
/// The resulting Iterator yields a `TreeType` which either contains the original
/// item, a new tree to be inserted or a pseudo item which indicates that a tree is finished.
///
/// # Type Parameters
Expand Down Expand Up @@ -97,7 +97,7 @@ where
if node.is_dir() && path == &self.path {
let (path, node, _) = self.item.take().unwrap();
self.item = self.iter.next();
let name = node.name();
let name = node.name().into_owned();
return Some(TreeType::NewTree((path, node, name)));
}
// Use mode 755 for missing dirs, so they can be accessed
Expand All @@ -106,7 +106,11 @@ where
..Default::default()
};
let node = Node::new_node(&p, NodeType::Dir, meta);
return Some(TreeType::NewTree((self.path.clone(), node, p)));
return Some(TreeType::NewTree((
self.path.clone(),
node,
p.into_owned(),
)));
}
}
// there wasn't any normal path component to process - return current item
Expand Down
29 changes: 14 additions & 15 deletions crates/core/src/backend/node.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
pub mod modification;

use std::{
cmp::Ordering,
ffi::{OsStr, OsString},
fmt::Debug,
path::Path,
str::FromStr,
};
use std::{borrow::Cow, cmp::Ordering, ffi::OsStr, fmt::Debug, path::Path};

#[cfg(not(windows))]
use std::fmt::Write;
Expand Down Expand Up @@ -355,8 +349,8 @@ impl Node {
/// # Panics
///
/// * If the name is not valid unicode
pub fn name(&self) -> OsString {
unescape_filename(&self.name).unwrap_or_else(|_| OsString::from_str(&self.name).unwrap())
pub fn name(&self) -> Cow<'_, OsStr> {
Comment thread
aawsome marked this conversation as resolved.
unescape_filename(&self.name).unwrap_or_else(|_| Cow::Borrowed(OsStr::new(&self.name)))
}
}

Expand Down Expand Up @@ -389,8 +383,8 @@ fn escape_filename(name: &OsStr) -> String {
///
/// * `s` - The escaped filename
#[cfg(windows)]
fn unescape_filename(s: &str) -> Result<OsString, core::convert::Infallible> {
OsString::from_str(s)
fn unescape_filename(s: &str) -> Result<Cow<'_, OsStr>, core::convert::Infallible> {
Ok(Cow::Borrowed(OsStr::new(s)))
}

#[cfg(not(windows))]
Expand Down Expand Up @@ -458,9 +452,13 @@ fn escape_filename(name: &OsStr) -> String {
///
/// * `s` - The escaped filename
// inspired by the enquote crate
fn unescape_filename(s: &str) -> NodeResult<'_, OsString> {
fn unescape_filename(s: &str) -> NodeResult<'_, Cow<'_, OsStr>> {
Comment thread
aawsome marked this conversation as resolved.
if !s.contains('\\') {
return Ok(Cow::Borrowed(OsStr::new(s)));
}

let mut chars = s.chars();
let mut u = Vec::new();
let mut u = Vec::with_capacity(s.len());
Comment thread
aawsome marked this conversation as resolved.
loop {
match chars.next() {
None => break,
Expand Down Expand Up @@ -549,7 +547,7 @@ fn unescape_filename(s: &str) -> NodeResult<'_, OsString> {
}
}

Ok(OsStr::from_bytes(&u).to_os_string())
Ok(Cow::Owned(OsStr::from_bytes(&u).to_os_string()))
}

#[cfg(not(windows))]
Expand All @@ -575,7 +573,8 @@ mod tests {
#[test]
fn escape_unescape_is_identity(bytes in prop::collection::vec(prop::num::u8::ANY, 0..65536)) {
let name = OsStr::from_bytes(&bytes);
prop_assert_eq!(name, unescape_filename(&escape_filename(name)).unwrap());
let escaped = escape_filename(name);
prop_assert_eq!(name, unescape_filename(escaped.as_ref()).unwrap());
}
}

Expand Down
17 changes: 9 additions & 8 deletions crates/core/src/blob/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ pub mod modify;
pub mod rewrite;

use std::{
borrow::Cow,
cmp::Ordering,
collections::{BTreeMap, BTreeSet, BinaryHeap},
ffi::{OsStr, OsString},
ffi::OsStr,
mem,
path::{Component, Path, PathBuf, Prefix},
str::{self, Utf8Error},
Expand Down Expand Up @@ -225,7 +226,7 @@ impl Tree {
be: &impl DecryptReadBackend,
index: &impl ReadGlobalIndex,
tree_id: TreeId,
path_comp: &[OsString],
path_comp: &[Cow<'_, OsStr>],
results_cache: &mut [BTreeMap<TreeId, Option<usize>>],
nodes: &mut BTreeMap<Node, usize>,
idx: usize,
Expand Down Expand Up @@ -435,18 +436,18 @@ pub struct FindMatches {
///
/// * If the component is a current or parent directory.
/// * If the component is not UTF-8 conform.
pub(crate) fn comp_to_osstr(p: Component<'_>) -> TreeResult<Option<OsString>> {
pub(crate) fn comp_to_osstr(p: Component<'_>) -> TreeResult<Option<Cow<'_, OsStr>>> {
let s = match p {
Component::RootDir => None,
Component::Prefix(p) => match p.kind() {
Prefix::Verbatim(p) | Prefix::DeviceNS(p) => Some(p.to_os_string()),
Prefix::VerbatimUNC(_, q) | Prefix::UNC(_, q) => Some(q.to_os_string()),
Prefix::VerbatimDisk(p) | Prefix::Disk(p) => Some(
Prefix::Verbatim(p) | Prefix::DeviceNS(p) => Some(Cow::Borrowed(p)),
Prefix::VerbatimUNC(_, q) | Prefix::UNC(_, q) => Some(Cow::Borrowed(q)),
Prefix::VerbatimDisk(p) | Prefix::Disk(p) => Some(Cow::Owned(
OsStr::new(str::from_utf8(&[p]).map_err(TreeErrorKind::PathIsNotUtf8Conform)?)
.to_os_string(),
),
)),
},
Component::Normal(p) => Some(p.to_os_string()),
Component::Normal(p) => Some(Cow::Borrowed(p)),
_ => return Err(TreeErrorKind::ContainsCurrentOrParentDirectory),
};
Ok(s)
Expand Down