diff --git a/src/uu/nl/src/helper.rs b/src/uu/nl/src/helper.rs index 5841819a406..150de9f8c9e 100644 --- a/src/uu/nl/src/helper.rs +++ b/src/uu/nl/src/helper.rs @@ -4,6 +4,8 @@ // file that was distributed with this source code. // spell-checker:ignore (ToDO) conv +use std::ffi::OsString; + use crate::options; use uucore::translate; @@ -23,7 +25,7 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &clap::ArgMatches) -> delimiter.clone() }; } - if let Some(val) = opts.get_one::(options::NUMBER_SEPARATOR) { + if let Some(val) = opts.get_one::(options::NUMBER_SEPARATOR) { settings.number_separator.clone_from(val); } settings.number_format = opts diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index f63be4022d0..15e4629d8dd 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -34,7 +34,7 @@ pub struct Settings { number_format: NumberFormat, renumber: bool, // The string appended to each line number output. - number_separator: String, + number_separator: OsString, } impl Default for Settings { @@ -50,7 +50,7 @@ impl Default for Settings { number_width: 6, number_format: NumberFormat::Right, renumber: true, - number_separator: String::from("\t"), + number_separator: OsString::from("\t"), } } } @@ -314,6 +314,7 @@ pub fn uu_app() -> Command { .short('s') .long(options::NUMBER_SEPARATOR) .help(translate!("nl-help-number-separator")) + .value_parser(clap::value_parser!(OsString)) .value_name("STRING"), ) .arg( @@ -389,7 +390,7 @@ fn nl(reader: &mut BufReader, stats: &mut Stats, settings: &Settings settings .number_format .format(line_number, settings.number_width), - settings.number_separator, + settings.number_separator.to_string_lossy(), ); // update line number for the potential next line match line_number.checked_add(settings.line_increment) { diff --git a/tests/by-util/test_nl.rs b/tests/by-util/test_nl.rs index 34a869dbbaa..14b30906dfe 100644 --- a/tests/by-util/test_nl.rs +++ b/tests/by-util/test_nl.rs @@ -11,7 +11,7 @@ use uutests::util_name; #[test] #[cfg(target_os = "linux")] -fn test_nl_non_utf8_paths() { +fn test_non_utf8_paths() { use std::os::unix::ffi::OsStringExt; let (at, mut ucmd) = at_and_ucmd!(); @@ -209,6 +209,28 @@ fn test_number_separator() { } } +#[test] +#[cfg(target_os = "linux")] +fn test_number_separator_non_utf8() { + use std::{ + ffi::{OsStr, OsString}, + os::unix::ffi::{OsStrExt, OsStringExt}, + }; + + let separator_bytes = [0xFF, 0xFE]; + let mut v = b"--number-separator=".to_vec(); + v.extend_from_slice(&separator_bytes); + + let arg = OsString::from_vec(v); + let separator = OsStr::from_bytes(&separator_bytes); + + new_ucmd!() + .arg(arg) + .pipe_in("test") + .succeeds() + .stdout_is(format!(" 1{}test\n", separator.to_string_lossy())); +} + #[test] fn test_starting_line_number() { for arg in ["-v10", "--starting-line-number=10"] {