Skip to content

Commit 74bf86d

Browse files
aweinstock314aweinstock
andauthored
env: Disallow __ALL__ in --{ignore,default,block}-signal (#11218)
Co-authored-by: aweinstock <avi@zellic.io>
1 parent 0474e55 commit 74bf86d

2 files changed

Lines changed: 70 additions & 21 deletions

File tree

src/uu/env/src/env.rs

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
55

6-
// spell-checker:ignore (ToDO) chdir progname subcommand subcommands unsets setenv putenv spawnp SIGSEGV SIGBUS sigaction Sigmask sigprocmask
6+
// spell-checker:ignore (ToDO) chdir progname subcommand subcommands unsets setenv putenv spawnp SIGSEGV SIGBUS sigaction Sigmask sigprocmask elidable
77

88
pub mod native_int_str;
99
pub mod split_iterator;
@@ -168,10 +168,6 @@ fn parse_signal_opt(target: &mut SignalRequest, opt: &OsStr) -> UResult<()> {
168168
if opt.is_empty() {
169169
return Ok(());
170170
}
171-
if opt == "__ALL__" {
172-
target.apply_all = true;
173-
return Ok(());
174-
}
175171

176172
for sig in opt
177173
.as_bytes()
@@ -193,7 +189,7 @@ fn parse_signal_opt(target: &mut SignalRequest, opt: &OsStr) -> UResult<()> {
193189
}
194190

195191
#[cfg(unix)]
196-
#[derive(Default)]
192+
#[derive(Default, Debug)]
197193
struct SignalRequest {
198194
apply_all: bool,
199195
signals: BTreeSet<usize>,
@@ -268,15 +264,21 @@ impl SignalActionLog {
268264
}
269265

270266
#[cfg(unix)]
271-
fn build_signal_request(matches: &clap::ArgMatches, option: &str) -> UResult<SignalRequest> {
267+
fn build_signal_request(
268+
matches: &clap::ArgMatches,
269+
option: &str,
270+
signal_apply_all: &BTreeSet<&str>,
271+
) -> UResult<SignalRequest> {
272272
let mut request = SignalRequest::default();
273273
let mut provided_values = 0usize;
274274

275275
let mut explicit_empty = false;
276276
if let Some(iter) = matches.get_many::<OsString>(option) {
277277
for opt in iter {
278278
if opt.is_empty() {
279-
explicit_empty = true;
279+
if !signal_apply_all.contains(option) {
280+
explicit_empty = true;
281+
}
280282
continue;
281283
}
282284
provided_values += 1;
@@ -538,6 +540,13 @@ struct EnvAppData {
538540
had_string_argument: bool,
539541
}
540542

543+
struct ParsedArguments {
544+
original_args: Vec<OsString>,
545+
matches: clap::ArgMatches,
546+
#[cfg(unix)]
547+
signal_apply_all: BTreeSet<&'static str>,
548+
}
549+
541550
impl EnvAppData {
542551
fn make_error_no_such_file_or_dir(&self, prog: &OsStr) -> Box<dyn UError> {
543552
uucore::show_error!(
@@ -634,17 +643,20 @@ impl EnvAppData {
634643
fn parse_arguments(
635644
&mut self,
636645
original_args: impl uucore::Args,
637-
) -> Result<(Vec<OsString>, clap::ArgMatches), Box<dyn UError>> {
646+
) -> Result<ParsedArguments, Box<dyn UError>> {
638647
let original_args: Vec<OsString> = original_args.collect();
639-
let mut args = self.process_all_string_arguments(&original_args)?;
648+
let args = self.process_all_string_arguments(&original_args)?;
649+
#[cfg(unix)]
650+
let mut signal_apply_all = BTreeSet::new();
640651

641-
for arg in &mut args {
652+
#[cfg(unix)]
653+
for arg in &args {
642654
if arg == "--ignore-signal" {
643-
*arg = OsString::from("--ignore-signal=__ALL__");
655+
signal_apply_all.insert(options::IGNORE_SIGNAL);
644656
} else if arg == "--default-signal" {
645-
*arg = OsString::from("--default-signal=__ALL__");
657+
signal_apply_all.insert(options::DEFAULT_SIGNAL);
646658
} else if arg == "--block-signal" {
647-
*arg = OsString::from("--block-signal=__ALL__");
659+
signal_apply_all.insert(options::BLOCK_SIGNAL);
648660
}
649661
}
650662

@@ -669,11 +681,21 @@ impl EnvAppData {
669681
}
670682
}
671683
};
672-
Ok((original_args, matches))
684+
Ok(ParsedArguments {
685+
original_args,
686+
matches,
687+
#[cfg(unix)]
688+
signal_apply_all,
689+
})
673690
}
674691

675692
fn run_env(&mut self, original_args: impl uucore::Args) -> UResult<()> {
676-
let (original_args, matches) = self.parse_arguments(original_args)?;
693+
let ParsedArguments {
694+
original_args,
695+
matches,
696+
#[cfg(unix)]
697+
signal_apply_all,
698+
} = self.parse_arguments(original_args)?;
677699

678700
self.do_debug_printing = self.do_debug_printing || (0 != matches.get_count("debug"));
679701
self.do_input_debug_printing = self
@@ -686,7 +708,11 @@ impl EnvAppData {
686708
}
687709
}
688710

689-
let mut opts = make_options(&matches)?;
711+
let mut opts = make_options(
712+
&matches,
713+
#[cfg(unix)]
714+
&signal_apply_all,
715+
)?;
690716

691717
apply_change_directory(&opts)?;
692718

@@ -888,7 +914,11 @@ fn apply_removal_of_all_env_vars(opts: &Options<'_>) {
888914
}
889915
}
890916

891-
fn make_options(matches: &clap::ArgMatches) -> UResult<Options<'_>> {
917+
#[cfg_attr(not(unix), allow(clippy::elidable_lifetime_names))]
918+
fn make_options<'a>(
919+
matches: &'a clap::ArgMatches,
920+
#[cfg(unix)] signal_apply_all: &BTreeSet<&'static str>,
921+
) -> UResult<Options<'a>> {
892922
let ignore_env = matches.get_flag("ignore-environment");
893923
let line_ending = LineEnding::from_zero_flag(matches.get_flag("null"));
894924
let running_directory = matches
@@ -907,11 +937,11 @@ fn make_options(matches: &clap::ArgMatches) -> UResult<Options<'_>> {
907937
.map(OsString::as_os_str);
908938

909939
#[cfg(unix)]
910-
let ignore_signal = build_signal_request(matches, options::IGNORE_SIGNAL)?;
940+
let ignore_signal = build_signal_request(matches, options::IGNORE_SIGNAL, signal_apply_all)?;
911941
#[cfg(unix)]
912-
let default_signal = build_signal_request(matches, options::DEFAULT_SIGNAL)?;
942+
let default_signal = build_signal_request(matches, options::DEFAULT_SIGNAL, signal_apply_all)?;
913943
#[cfg(unix)]
914-
let block_signal = build_signal_request(matches, options::BLOCK_SIGNAL)?;
944+
let block_signal = build_signal_request(matches, options::BLOCK_SIGNAL, signal_apply_all)?;
915945
#[cfg(unix)]
916946
let list_signal_handling = matches.get_flag(options::LIST_SIGNAL_HANDLING);
917947

tests/by-util/test_env.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,3 +2009,22 @@ fn test_ignore_signal_pipe_broken_pipe_regression() {
20092009
"With --ignore-signal=PIPE, process should exit gracefully (0 or 1), got: {ignore_signal_exit_code}"
20102010
);
20112011
}
2012+
2013+
#[test]
2014+
#[cfg(unix)]
2015+
fn test_env_disallow_double_underscore_all() {
2016+
new_ucmd!()
2017+
.args(&["--ignore-signal=__ALL__", "true"])
2018+
.fails()
2019+
.stderr_contains("invalid signal");
2020+
2021+
new_ucmd!()
2022+
.args(&["--default-signal=__ALL__", "true"])
2023+
.fails()
2024+
.stderr_contains("invalid signal");
2025+
2026+
new_ucmd!()
2027+
.args(&["--block-signal=__ALL__", "true"])
2028+
.fails()
2029+
.stderr_contains("invalid signal");
2030+
}

0 commit comments

Comments
 (0)