nl -w N accepts an arbitrarily large line-number field width N. A large -w makes number_width + 1 exceed isize::MAX and str::repeat aborts with a capacity overflow.
$ printf '\n' | nl -w 9223372036854775807
thread 'main' panicked at library/alloc/src/slice.rs:524:23:
capacity overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Aborted (core dumped)
$ echo $?
134
GNU coreutils rejects the same width up front, and in fact bounds -w to
[1, INT_MAX] (a C int), so it rejects anything above 2147483647 (2^31 - 1):
$ printf '\n' | /usr/bin/nl -w 2147483647 # INT_MAX: accepted
$ echo $?
0
$ printf '\n' | /usr/bin/nl -w 2147483648 # INT_MAX + 1: rejected
/usr/bin/nl: invalid line number field width: '2147483648': Value too large for defined data type
$ echo $?
1
Root cause
number_width is parsed with an unbounded usize value parser
(src/uu/nl/src/nl.rs):
Arg::new(options::NUMBER_WIDTH)
.short('w')
.long(options::NUMBER_WIDTH)
.value_name("NUMBER")
.value_parser(clap::value_parser!(usize)),
and the unnumbered-line branch pads with repeat(number_width + 1) (nl.rs:455):
} else {
let prefix = " ".repeat(settings.number_width + 1); // <-- +1 can exceed isize::MAX
writer
.write_all(prefix.as_bytes())
.map_err_context(|| translate!("nl-error-could-not-write"))?;
}
str::repeat(n) allocates a buffer of n * self.len() bytes and panics with capacity overflow when that exceeds isize::MAX. With number_width = isize::MAX, number_width + 1 is exactly isize::MAX + 1, so the very first pad overflows.
Found by our static analysis tooling.
nl -w Naccepts an arbitrarily large line-number field widthN. A large-wmakesnumber_width + 1exceedisize::MAXandstr::repeataborts with a capacity overflow.GNU coreutils rejects the same width up front, and in fact bounds
-wto[1, INT_MAX](a Cint), so it rejects anything above2147483647(2^31 - 1):Root cause
number_widthis parsed with an unboundedusizevalue parser(
src/uu/nl/src/nl.rs):and the unnumbered-line branch pads with
repeat(number_width + 1)(nl.rs:455):str::repeat(n)allocates a buffer ofn * self.len()bytes and panics withcapacity overflowwhen that exceedsisize::MAX. Withnumber_width = isize::MAX,number_width + 1is exactlyisize::MAX + 1, so the very first pad overflows.Found by our static analysis tooling.