diff options
author | cygnus9 <cygnus9@users.noreply.github.com> | 2019-01-03 16:32:43 +0100 |
---|---|---|
committer | Alex Crichton <alex@alexcrichton.com> | 2019-01-03 09:32:43 -0600 |
commit | 65e890da15e033f08413f650c48b192f6cf5c44b (patch) | |
tree | e6cf80ca0bb7fc2fa7732a13b86d31e3c5bf3895 | |
parent | dd00ccac21de31bc72bf397d6640133499d92a19 (diff) | |
download | ssh2-rs-65e890da15e033f08413f650c48b192f6cf5c44b.zip |
Normalize to Unix-style path separators (#102)
-rw-r--r-- | src/util.rs | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/util.rs b/src/util.rs index 31637dc..414bbb2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::path::Path; use {raw, Session, Error}; @@ -28,22 +29,36 @@ pub trait SessionBinding<'sess>: Sized { } #[cfg(unix)] -pub fn path2bytes(p: &Path) -> Result<&[u8], Error> { +pub fn path2bytes(p: &Path) -> Result<Cow<[u8]>, Error> { use std::os::unix::prelude::*; use std::ffi::OsStr; let s: &OsStr = p.as_ref(); - check(s.as_bytes()) + check(Cow::Borrowed(s.as_bytes())) } #[cfg(windows)] -pub fn path2bytes(p: &Path) -> Result<&[u8], Error> { - match p.to_str() { - Some(s) => check(s.as_bytes()), - None => Err(Error::new(raw::LIBSSH2_ERROR_INVAL, - "only unicode paths on windows may be used")), - } +pub fn path2bytes(p: &Path) -> Result<Cow<[u8]>, Error> { + p.to_str() + .map(|s| s.as_bytes()) + .ok_or_else(|| Error::new(raw::LIBSSH2_ERROR_INVAL, + "only unicode paths on windows may be used")) + .map(|bytes| { + if bytes.contains(&b'\\') { + // Normalize to Unix-style path separators + let mut bytes = bytes.to_owned(); + for b in &mut bytes { + if *b == b'\\' { + *b = b'/'; + } + } + Cow::Owned(bytes) + } else { + Cow::Borrowed(bytes) + } + }) + .and_then(check) } -fn check(b: &[u8]) -> Result<&[u8], Error> { +fn check(b: Cow<[u8]>) -> Result<Cow<[u8]>, Error> { if b.iter().any(|b| *b == 0) { Err(Error::new(raw::LIBSSH2_ERROR_INVAL, "path provided contains a 0 byte")) |