diff --git a/src/uu/expand/src/expand.rs b/src/uu/expand/src/expand.rs index 2f0c911adaf..1c44756e223 100644 --- a/src/uu/expand/src/expand.rs +++ b/src/uu/expand/src/expand.rs @@ -193,11 +193,12 @@ fn expand_shortcuts(args: Vec) -> Vec { let mut processed_args = Vec::with_capacity(args.len()); for arg in args { - if let Some(arg) = arg.to_str() - && arg.starts_with('-') - && arg[1..].chars().all(is_digit_or_comma) + if let Some(shortcut) = arg + .to_str() + .and_then(|arg| arg.strip_prefix('-')) + .filter(|shortcut| !shortcut.is_empty() && shortcut.chars().all(is_digit_or_comma)) { - arg[1..] + shortcut .split(',') .filter(|s| !s.is_empty()) .for_each(|s| processed_args.push(OsString::from(format!("--tabs={s}")))); diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index 1353585a584..d7029e09639 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -201,8 +201,11 @@ fn expand_shortcuts(args: Vec) -> Vec { for arg in args { if let Some(arg) = arg.to_str() { - if arg.starts_with('-') && arg[1..].chars().all(is_digit_or_comma) { - arg[1..] + if let Some(shortcut) = arg + .strip_prefix('-') + .filter(|shortcut| !shortcut.is_empty() && shortcut.chars().all(is_digit_or_comma)) + { + shortcut .split(',') .filter(|s| !s.is_empty()) .for_each(|s| processed_args.push(OsString::from(format!("--tabs={s}")))); diff --git a/tests/by-util/test_expand.rs b/tests/by-util/test_expand.rs index c943854b8ba..4c37b54ea5d 100644 --- a/tests/by-util/test_expand.rs +++ b/tests/by-util/test_expand.rs @@ -7,13 +7,24 @@ use rstest::rstest; use uucore::display::Quotable; -use uutests::new_ucmd; +use uutests::{at_and_ucmd, new_ucmd}; #[test] fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } +#[test] +fn test_bare_dash_reads_stdin_in_file_list() { + let (at, mut ucmd) = at_and_ucmd!(); + at.write("file", "file\n"); + + ucmd.args(&["-", "file"]) + .pipe_in("stdin\n") + .succeeds() + .stdout_is("stdin\nfile\n"); +} + #[test] fn test_with_tab() { new_ucmd!() diff --git a/tests/by-util/test_unexpand.rs b/tests/by-util/test_unexpand.rs index 49a28723746..cbe838afff5 100644 --- a/tests/by-util/test_unexpand.rs +++ b/tests/by-util/test_unexpand.rs @@ -13,6 +13,35 @@ fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } +#[test] +fn test_bare_dash_reads_stdin_in_file_list() { + let (at, mut ucmd) = at_and_ucmd!(); + at.write("file", "file\n"); + + ucmd.args(&["-", "file"]) + .pipe_in("stdin\n") + .succeeds() + .stdout_is("stdin\nfile\n"); +} + +#[test] +fn test_bare_dash_does_not_force_first_only() { + new_ucmd!() + .args(&["-t", "3", "-"]) + .pipe_in("a b\n") + .succeeds() + .stdout_is("a\tb\n"); +} + +#[test] +fn test_first_only_with_bare_stdin_operand() { + new_ucmd!() + .args(&["--first-only", "-"]) + .pipe_in(" A B\n") + .succeeds() + .stdout_is("\tA B\n"); +} + #[rstest] #[case::unexpand_init_0(&["-t4"], " 1\n 2\n 3\n 4\n", " 1\n 2\n 3\n\t4\n")] #[case::unexpand_init_1(&["-t4"], " 5\n 6\n 7\n 8\n", "\t 5\n\t 6\n\t 7\n\t\t8\n")]