-
Notifications
You must be signed in to change notification settings - Fork 38
Allow conversion of std::process::Command
into a openssh::Command
given a openssh::Session
.
#112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e314422
d9ba8d3
dd64633
9743a5e
0a69ed1
974cd52
cca22b1
66cecba
511c62c
d14a4c2
32a8960
08b77a5
5d9a112
7d84871
c4baafd
7e84beb
7fcfaf2
13d865a
c4ded38
67d0885
6970753
8207907
10687fb
020366a
6842e5a
e09d2fd
f30d34e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
//! Escape characters that may have special meaning in a shell, including spaces. | ||
//! This is a modified version of the [`shell-escape::unix`] module of [`shell-escape`] crate. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we submit a PR to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great suggestion! I've initiated a PR to |
||
//! | ||
//! [`shell-escape`]: https://crates.io/crates/shell-escape | ||
//! [`shell-escape::unix`]: https://docs.rs/shell-escape/latest/src/shell_escape/lib.rs.html#101 | ||
|
||
use std::{ | ||
borrow::Cow, | ||
ffi::{OsStr, OsString}, | ||
os::unix::ffi::OsStrExt, | ||
os::unix::ffi::OsStringExt, | ||
}; | ||
|
||
fn allowed(byte: u8) -> bool { | ||
matches!(byte, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'_' | b'=' | b'/' | b',' | b'.' | b'+') | ||
} | ||
|
||
/// Escape characters that may have special meaning in a shell, including spaces. | ||
/// | ||
/// **Note**: This function is an adaptation of [`shell-escape::unix::escape`]. | ||
/// This function exists only for type compatibility and the implementation is | ||
/// almost exactly the same as [`shell-escape::unix::escape`]. | ||
/// | ||
/// [`shell-escape::unix::escape`]: https://docs.rs/shell-escape/latest/src/shell_escape/lib.rs.html#101 | ||
/// | ||
pub(crate) fn escape(s: &OsStr) -> Cow<'_, OsStr> { | ||
let as_bytes = s.as_bytes(); | ||
let all_allowed = as_bytes.iter().copied().all(allowed); | ||
|
||
if !as_bytes.is_empty() && all_allowed { | ||
return Cow::Borrowed(s); | ||
} | ||
|
||
let mut escaped = Vec::with_capacity(as_bytes.len() + 2); | ||
escaped.push(b'\''); | ||
|
||
for &b in as_bytes { | ||
match b { | ||
b'\'' | b'!' => { | ||
escaped.reserve(4); | ||
escaped.push(b'\''); | ||
NobodyXu marked this conversation as resolved.
Show resolved
Hide resolved
aalekhpatel07 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
escaped.push(b'\\'); | ||
escaped.push(b); | ||
escaped.push(b'\''); | ||
} | ||
_ => escaped.push(b), | ||
} | ||
} | ||
escaped.push(b'\''); | ||
OsString::from_vec(escaped).into() | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
fn test_escape_case(input: &str, expected: &str) { | ||
NobodyXu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
test_escape_from_bytes(input.as_bytes(), expected.as_bytes()) | ||
} | ||
|
||
fn test_escape_from_bytes(input: &[u8], expected: &[u8]) { | ||
let input_os_str = OsStr::from_bytes(input); | ||
let observed_os_str = escape(input_os_str); | ||
let expected_os_str = OsStr::from_bytes(expected); | ||
assert_eq!(observed_os_str, expected_os_str); | ||
} | ||
|
||
// These tests are courtesy of the `shell-escape` crate. | ||
#[test] | ||
fn test_escape() { | ||
test_escape_case( | ||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_=/,.+", | ||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_=/,.+", | ||
); | ||
test_escape_case("--aaa=bbb-ccc", "--aaa=bbb-ccc"); | ||
test_escape_case( | ||
"linker=gcc -L/foo -Wl,bar", | ||
r#"'linker=gcc -L/foo -Wl,bar'"#, | ||
); | ||
test_escape_case(r#"--features="default""#, r#"'--features="default"'"#); | ||
test_escape_case(r#"'!\$`\\\n "#, r#"''\'''\!'\$`\\\n '"#); | ||
test_escape_case("", r#"''"#); | ||
test_escape_case(" ", r#"' '"#); | ||
test_escape_case("*", r#"'*'"#); | ||
|
||
test_escape_from_bytes( | ||
&[0x66, 0x6f, 0x80, 0x6f], | ||
&[b'\'', 0x66, 0x6f, 0x80, 0x6f, b'\''], | ||
); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.