Skip to content

Commit 93fa095

Browse files
leeeweesylvestre
authored andcommitted
numfmt: reject an oversized --from-unit/--to-unit instead of panicking
parse_unit_size computed the unit size as `n * multiplier` with an unchecked multiplication. A large numeric part with a suffix overflows usize: when the product wraps to exactly 0 (e.g. `--to-unit=18014398509481984Ki`, 2^54 * 1024 = 2^64), the zero unit later reaches `integer % to_unit` and aborts with a remainder-by-zero; a merely-huge value overflows the multiply itself under overflow-checks. Use `checked_mul` so an out-of-range product falls through to the existing "invalid unit size" error (exit 1), matching GNU numfmt, whose `unit_to_umax` rejects a value that overflows uintmax_t.
1 parent 314110b commit 93fa095

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

src/uu/numfmt/src/numfmt.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,12 @@ fn parse_unit_size(s: &str) -> Result<usize> {
200200
if number.is_empty() {
201201
return Ok(multiplier);
202202
}
203-
if let Ok(n) = number.parse::<usize>() {
204-
return Ok(n * multiplier);
203+
if let Some(size) = number
204+
.parse::<usize>()
205+
.ok()
206+
.and_then(|n| n.checked_mul(multiplier))
207+
{
208+
return Ok(size);
205209
}
206210
}
207211
}

tests/by-util/test_numfmt.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,13 @@ fn test_to_unit() {
878878
#[test]
879879
fn test_invalid_unit_size() {
880880
let commands = vec!["from", "to"];
881-
let invalid_sizes = vec!["A", "0", "18446744073709551616"];
881+
let invalid_sizes = vec![
882+
"A",
883+
"0",
884+
"18446744073709551616",
885+
"18446744073709551615K",
886+
"18014398509481984Ki",
887+
];
882888

883889
for command in commands {
884890
for invalid_size in &invalid_sizes {

0 commit comments

Comments
 (0)