From f7b684a6fd6054a22b6e824ec5282493ee1c29db Mon Sep 17 00:00:00 2001 From: komal0000 Date: Sun, 25 Oct 2026 16:00:07 +0545 Subject: [PATCH 1/2] sort: reject mixing silent and diagnosing --check modes --- src/uu/sort/src/sort.rs | 27 ++++++++++++++------------- tests/by-util/test_sort.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 8a80d585946..3da91502c46 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -2368,21 +2368,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { settings.line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO_TERMINATED)); settings.merge = matches.get_flag(options::MERGE); - settings.check = matches.contains_id(options::check::CHECK); - if settings.check && matches.get_flag(options::check::CHECK_SILENT) { + let check_modes: Vec<&str> = matches + .get_many::(options::check::CHECK) + .map(|modes| modes.map(String::as_str).collect()) + .unwrap_or_default(); + let check_silent = matches.get_flag(options::check::CHECK_SILENT) + || check_modes + .iter() + .any(|m| matches!(*m, options::check::SILENT | options::check::QUIET)); + let check_diagnose = check_modes.contains(&options::check::DIAGNOSE_FIRST); + if check_silent && check_diagnose { return Err(incompatible_options_error("cC")); } - if matches.get_flag(options::check::CHECK_SILENT) - || matches!( - matches - .get_one::(options::check::CHECK) - .map(String::as_str), - Some(options::check::SILENT | options::check::QUIET) - ) - { - settings.check_silent = true; - settings.check = true; - } + settings.check = check_silent || check_diagnose; + settings.check_silent = check_silent; if matches.contains_id(options::OUTPUT) && settings.check { let opts = if settings.check_silent { "Co" } else { "co" }; @@ -2591,6 +2590,8 @@ pub fn uu_app() -> Command { .long(options::check::CHECK) .require_equals(true) .num_args(0..) + .default_missing_value(options::check::DIAGNOSE_FIRST) + .action(ArgAction::Append) .value_parser(ShortcutValueParser::new([ options::check::SILENT, options::check::QUIET, diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index c0d556026ad..cf3e0e7c870 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -1579,6 +1579,39 @@ fn test_check_silent() { } } +#[test] +fn test_check_repeated_modes() { + for args in [ + ["--check=silent", "--check=diagnose-first"], + ["--check=diagnose-first", "--check=quiet"], + ["-c", "--check=quiet"], + ["--check=silent", "-c"], + ] { + new_ucmd!() + .args(&args) + .arg("check_fail.txt") + .fails_with_code(2) + .stderr_only("sort: options '-cC' are incompatible\n"); + } + + for args in [ + ["--check=quiet", "-C"], + ["-C", "--check=silent"], + ["--check=quiet", "--check=silent"], + ] { + new_ucmd!() + .args(&args) + .arg("check_fail.txt") + .fails_with_code(1) + .no_output(); + } + + new_ucmd!() + .args(&["--check=diagnose-first", "-c", "check_fail.txt"]) + .fails_with_code(1) + .stderr_only("sort: check_fail.txt:6: disorder: 5\n"); +} + #[test] fn test_check_stops_early_without_panicking() { // `--check` returns as soon as it finds the first disorder. That used to drop the From ed025f5c5787684ffbdcb5060d0828db14249715 Mon Sep 17 00:00:00 2001 From: komal0000 Date: Mon, 26 Oct 2026 08:56:01 +0545 Subject: [PATCH 2/2] sort: test -c=silent -c=diagnose-first from the issue --- tests/by-util/test_sort.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index cf3e0e7c870..b2cf0b8940a 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -1583,6 +1583,7 @@ fn test_check_silent() { fn test_check_repeated_modes() { for args in [ ["--check=silent", "--check=diagnose-first"], + ["-c=silent", "-c=diagnose-first"], ["--check=diagnose-first", "--check=quiet"], ["-c", "--check=quiet"], ["--check=silent", "-c"],