diff --git a/src/uu/nl/src/helper.rs b/src/uu/nl/src/helper.rs index 6bbec85f444..0408adac65a 100644 --- a/src/uu/nl/src/helper.rs +++ b/src/uu/nl/src/helper.rs @@ -7,7 +7,6 @@ use std::ffi::OsString; use crate::options; -use uucore::translate; // parse_options loads the options into the settings, returning an array of // error messages. @@ -61,10 +60,8 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &clap::ArgMatches) -> Some(Ok(style)) => settings.footer_numbering = style, Some(Err(message)) => errs.push(message), } - match opts.get_one::(options::NUMBER_WIDTH) { - None => {} - Some(num) if *num > 0 => settings.number_width = *num, - Some(_) => errs.push(translate!("nl-error-invalid-line-width", "value" => "0")), + if let Some(&num) = opts.get_one::(options::NUMBER_WIDTH) { + settings.number_width = num as usize; } if let Some(num) = opts.get_one::(options::JOIN_BLANK_LINES) { settings.join_blank_lines = *num; diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index 37ec112451a..34a4009c24c 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -376,7 +376,7 @@ pub fn uu_app() -> Command { .long(options::NUMBER_WIDTH) .help(translate!("nl-help-number-width")) .value_name("NUMBER") - .value_parser(clap::value_parser!(usize)), + .value_parser(clap::value_parser!(u64).range(1..=(i32::MAX as u64))), ) } diff --git a/tests/by-util/test_nl.rs b/tests/by-util/test_nl.rs index c08c6a7b243..b5aff70629d 100644 --- a/tests/by-util/test_nl.rs +++ b/tests/by-util/test_nl.rs @@ -183,10 +183,32 @@ fn test_number_width_zero() { new_ucmd!() .arg(arg) .fails() - .stderr_contains("Invalid line number field width: ‘0’: Numerical result out of range"); + .stderr_contains("is not in 1..=2147483647"); } } +#[test] +fn test_number_width_too_large() { + // Values > i32::MAX must be rejected to match GNU nl behaviour and avoid + // a capacity-overflow panic in " ".repeat(number_width + 1). + for arg in ["-w2147483648", "--number-width=2147483648"] { + new_ucmd!() + .arg(arg) + .pipe_in("") + .fails() + .stderr_contains("is not in 1..=2147483647"); + } +} + +#[test] +fn test_number_width_max_i32() { + // i32::MAX (2147483647) is the largest value GNU nl accepts; it must not panic. + new_ucmd!() + .args(&["-w", "2147483647"]) + .pipe_in("") + .succeeds(); +} + #[test] fn test_invalid_number_width() { for arg in ["-winvalid", "--number-width=invalid"] {