summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcygnus9 <cygnus9@users.noreply.github.com>2019-01-03 16:32:43 +0100
committerAlex Crichton <alex@alexcrichton.com>2019-01-03 09:32:43 -0600
commit65e890da15e033f08413f650c48b192f6cf5c44b (patch)
treee6cf80ca0bb7fc2fa7732a13b86d31e3c5bf3895
parentdd00ccac21de31bc72bf397d6640133499d92a19 (diff)
downloadssh2-rs-65e890da15e033f08413f650c48b192f6cf5c44b.zip
Normalize to Unix-style path separators (#102)
-rw-r--r--src/util.rs33
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"))