diff --git a/src/uu/nl/src/helper.rs b/src/uu/nl/src/helper.rs index 6bbec85f444..bf2e68c3030 100644 --- a/src/uu/nl/src/helper.rs +++ b/src/uu/nl/src/helper.rs @@ -63,8 +63,11 @@ pub fn parse_options(settings: &mut crate::Settings, opts: &clap::ArgMatches) -> } 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")), + Some(num) if *num > 0 && *num <= i32::MAX as usize => settings.number_width = *num, + Some(num) => errs.push(translate!( + "nl-error-invalid-line-width", + "value" => num.to_string() + )), } if let Some(num) = opts.get_one::(options::JOIN_BLANK_LINES) { settings.join_blank_lines = *num; diff --git a/tests/by-util/test_nl.rs b/tests/by-util/test_nl.rs index c08c6a7b243..57bb0849134 100644 --- a/tests/by-util/test_nl.rs +++ b/tests/by-util/test_nl.rs @@ -187,6 +187,28 @@ fn test_number_width_zero() { } } +#[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("Invalid line number field width: '2147483648': Numerical result out of range"); + } +} + +#[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"] {