Remove possibility to use '--exec <cmd>' with a single dash

This commit is contained in:
sharkdp 2020-04-03 12:00:44 +02:00 committed by David Peter
parent c79d1638f5
commit 342d12db3f
3 changed files with 20 additions and 161 deletions

View File

@ -1,5 +1,5 @@
use std::borrow::Cow;
use std::ffi::{OsStr, OsString};
use std::ffi::OsStr;
#[cfg(any(unix, target_os = "redox"))]
pub fn osstr_to_bytes(input: &OsStr) -> Cow<[u8]> {
@ -16,118 +16,3 @@ pub fn osstr_to_bytes(input: &OsStr) -> Cow<[u8]> {
Cow::Borrowed(string) => Cow::Borrowed(string.as_bytes()),
}
}
/// Traverse args_os, looking for -exec and replacing it with --exec.
///
/// # Returns
///
/// * The args, with substitution if required
pub fn transform_args_with_exec<I>(original: I) -> Vec<OsString>
where
I: Iterator<Item = OsString>,
{
let mut in_exec_opt = false;
let target = OsString::from("-exec");
let long_start = OsString::from("--exec");
let short_start = OsString::from("-x");
let exec_end = OsString::from(";");
original.fold(vec![], |mut args, curr| {
if in_exec_opt {
if curr == exec_end {
in_exec_opt = false;
}
args.push(curr);
return args;
}
if curr == target || curr == long_start || curr == short_start {
args.push(if curr == target {
OsString::from("--exec")
} else {
curr
});
in_exec_opt = true;
} else {
args.push(curr);
}
args
})
}
#[cfg(test)]
mod tests {
use super::*;
fn oss_vec(strs: &[&str]) -> Vec<OsString> {
strs.into_iter().map(OsString::from).collect()
}
/// Ensure that -exec gets transformed into --exec
#[test]
fn normal_exec_substitution() {
let original = oss_vec(&["fd", "foo", "-exec", "cmd"]);
let expected = oss_vec(&["fd", "foo", "--exec", "cmd"]);
let actual = transform_args_with_exec(original.into_iter());
assert_eq!(expected, actual);
}
/// Ensure that --exec is not touched
#[test]
fn passthru_of_original_exec() {
let original = oss_vec(&["fd", "foo", "--exec", "cmd"]);
let expected = oss_vec(&["fd", "foo", "--exec", "cmd"]);
let actual = transform_args_with_exec(original.into_iter());
assert_eq!(expected, actual);
}
#[test]
fn temp_check_that_exec_context_observed() {
let original = oss_vec(&[
"fd",
"foo",
"-exec",
"cmd",
"-exec",
"ls",
";",
"-exec",
"rm",
";",
"--exec",
"find",
"-exec",
"rm",
";",
"-x",
"foo",
"-exec",
"something",
";",
"-exec",
]);
let expected = oss_vec(&[
"fd",
"foo",
"--exec",
"cmd",
"-exec",
"ls",
";",
"--exec",
"rm",
";",
"--exec",
"find",
"-exec",
"rm",
";",
"-x",
"foo",
"-exec",
"something",
";",
"--exec",
]);
let actual = transform_args_with_exec(original.into_iter());
assert_eq!(expected, actual);
}
}

View File

@ -27,7 +27,6 @@ use regex::bytes::{RegexBuilder, RegexSetBuilder};
use crate::exec::CommandTemplate;
use crate::filetypes::FileTypes;
use crate::filter::{SizeFilter, TimeFilter};
use crate::internal::transform_args_with_exec;
use crate::options::Options;
use crate::regex_helper::pattern_has_uppercase_char;
@ -37,8 +36,7 @@ use crate::regex_helper::pattern_has_uppercase_char;
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
fn main() {
let checked_args = transform_args_with_exec(env::args_os());
let matches = app::build_app().get_matches_from(checked_args);
let matches = app::build_app().get_matches_from(env::args_os());
// Set the current working directory of the process
if let Some(base_directory) = matches.value_of("base-directory") {

View File

@ -1064,28 +1064,11 @@ fn test_excludes() {
/// Shell script execution (--exec)
#[test]
fn test_exec() {
assert_exec_output("--exec");
}
/// Shell script execution using -exec
#[test]
fn test_exec_substitution() {
assert_exec_output("-exec");
}
// Shell script execution using -x
#[test]
fn test_exec_short_arg() {
assert_exec_output("-x");
}
#[cfg(test)]
fn assert_exec_output(exec_style: &str) {
let (te, abs_path) = get_test_env_with_abs_path(DEFAULT_DIRS, DEFAULT_FILES);
// TODO Windows tests: D:file.txt \file.txt \\server\share\file.txt ...
if !cfg!(windows) {
te.assert_output(
&["--absolute-path", "foo", exec_style, "echo"],
&["--absolute-path", "foo", "--exec", "echo"],
&format!(
"{abs_path}/a.foo
{abs_path}/one/b.foo
@ -1098,7 +1081,7 @@ fn assert_exec_output(exec_style: &str) {
);
te.assert_output(
&["foo", exec_style, "echo", "{}"],
&["foo", "--exec", "echo", "{}"],
"a.foo
one/b.foo
one/two/C.Foo2
@ -1108,7 +1091,7 @@ fn assert_exec_output(exec_style: &str) {
);
te.assert_output(
&["foo", exec_style, "echo", "{.}"],
&["foo", "--exec", "echo", "{.}"],
"a
one/b
one/two/C
@ -1118,7 +1101,7 @@ fn assert_exec_output(exec_style: &str) {
);
te.assert_output(
&["foo", exec_style, "echo", "{/}"],
&["foo", "--exec", "echo", "{/}"],
"a.foo
b.foo
C.Foo2
@ -1128,7 +1111,7 @@ fn assert_exec_output(exec_style: &str) {
);
te.assert_output(
&["foo", exec_style, "echo", "{/.}"],
&["foo", "--exec", "echo", "{/.}"],
"a
b
C
@ -1138,7 +1121,7 @@ fn assert_exec_output(exec_style: &str) {
);
te.assert_output(
&["foo", exec_style, "echo", "{//}"],
&["foo", "--exec", "echo", "{//}"],
".
one
one/two
@ -1147,29 +1130,19 @@ fn assert_exec_output(exec_style: &str) {
one/two/three",
);
te.assert_output(&["e1", exec_style, "printf", "%s.%s\n"], "e1 e2.");
te.assert_output(&["e1", "--exec", "printf", "%s.%s\n"], "e1 e2.");
}
}
#[test]
fn test_exec_batch() {
assert_exec_batch_output("--exec-batch");
}
#[test]
fn test_exec_batch_short_arg() {
assert_exec_batch_output("-X");
}
#[cfg(test)]
fn assert_exec_batch_output(exec_style: &str) {
let (te, abs_path) = get_test_env_with_abs_path(DEFAULT_DIRS, DEFAULT_FILES);
let te = te.normalize_line(true);
// TODO Test for windows
if !cfg!(windows) {
te.assert_output(
&["--absolute-path", "foo", exec_style, "echo"],
&["--absolute-path", "foo", "--exec-batch", "echo"],
&format!(
"{abs_path}/a.foo {abs_path}/one/b.foo {abs_path}/one/two/C.Foo2 {abs_path}/one/two/c.foo {abs_path}/one/two/three/d.foo {abs_path}/one/two/three/directory_foo",
abs_path = &abs_path
@ -1177,34 +1150,37 @@ fn assert_exec_batch_output(exec_style: &str) {
);
te.assert_output(
&["foo", exec_style, "echo", "{}"],
&["foo", "--exec-batch", "echo", "{}"],
"a.foo one/b.foo one/two/C.Foo2 one/two/c.foo one/two/three/d.foo one/two/three/directory_foo",
);
te.assert_output(
&["foo", exec_style, "echo", "{/}"],
&["foo", "--exec-batch", "echo", "{/}"],
"a.foo b.foo C.Foo2 c.foo d.foo directory_foo",
);
te.assert_output(&["no_match", exec_style, "echo", "Matched: ", "{/}"], "");
te.assert_output(
&["no_match", "--exec-batch", "echo", "Matched: ", "{/}"],
"",
);
te.assert_error(
&["foo", exec_style, "echo", "{}", "{}"],
&["foo", "--exec-batch", "echo", "{}", "{}"],
"[fd error]: Only one placeholder allowed for batch commands",
);
te.assert_error(
&["foo", exec_style, "echo", "{/}", ";", "-x", "echo"],
&["foo", "--exec-batch", "echo", "{/}", ";", "-x", "echo"],
"error: The argument '--exec <cmd>' cannot be used with '--exec-batch <cmd>'",
);
te.assert_error(
&["foo", exec_style],
&["foo", "--exec-batch"],
"error: The argument '--exec-batch <cmd>' requires a value but none was supplied",
);
te.assert_error(
&["foo", exec_style, "echo {}"],
&["foo", "--exec-batch", "echo {}"],
"[fd error]: First argument of exec-batch is expected to be a fixed executable",
);
}