diff --git a/src/uu/nl/src/helper.rs b/src/uu/nl/src/helper.rs index d801ca713e..28274ca8e6 100644 --- a/src/uu/nl/src/helper.rs +++ b/src/uu/nl/src/helper.rs @@ -67,9 +67,11 @@ 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) { + // The upper bound is enforced by clap (see the argument definition); only + // the zero case is reported here, to match GNU's message for it. + match opts.get_one::(options::NUMBER_WIDTH) { None => {} - Some(num) if *num > 0 => settings.number_width = *num, + Some(num) if *num > 0 => settings.number_width = *num as usize, Some(_) => errs.push(translate!("nl-error-invalid-line-width", "value" => "0")), } if let Some(num) = opts.get_one::(options::JOIN_BLANK_LINES) { diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index b2ce91872d..382ee0b0c4 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -376,7 +376,10 @@ pub fn uu_app() -> Command { .long(options::NUMBER_WIDTH) .help(translate!("nl-help-number-width")) .value_name("NUMBER") - .value_parser(clap::value_parser!(usize)), + // Bound the width to a C int like GNU. This rejects a huge width + // up front instead of letting a later `" ".repeat(width + 1)` + // abort with a capacity overflow (#13347). + .value_parser(clap::value_parser!(u64).range(..=i32::MAX as u64)), ) } diff --git a/tests/by-util/test_nl.rs b/tests/by-util/test_nl.rs index dcfafd3201..62b7b6bee0 100644 --- a/tests/by-util/test_nl.rs +++ b/tests/by-util/test_nl.rs @@ -187,6 +187,17 @@ fn test_number_width_zero() { } } +#[test] +fn test_number_width_above_int_max_is_rejected() { + // A field width above i32::MAX is rejected up front by clap, matching GNU's + // C-int bound, instead of aborting with a capacity overflow (#13347). + new_ucmd!() + .args(&["-w", "2147483648"]) + .pipe_in("x\n") + .fails() + .stderr_contains("is not in 0..=2147483647"); +} + #[test] fn test_invalid_number_width() { for arg in ["-winvalid", "--number-width=invalid"] {