Skip to content

Commit 0b63ffc

Browse files
committed
printf: Format String Parsing Overflow Causes Panic
Closes: uutils#9697
1 parent 2000af8 commit 0b63ffc

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

src/uucore/src/lib/features/format/spec.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -595,14 +595,10 @@ fn eat_number(rest: &mut &[u8], index: &mut usize) -> Option<usize> {
595595
match rest[*index..].iter().position(|b| !b.is_ascii_digit()) {
596596
None | Some(0) => None,
597597
Some(i) => {
598-
// TODO: This might need to handle errors better
599-
// For example in case of overflow.
600-
let parsed = std::str::from_utf8(&rest[*index..(*index + i)])
601-
.unwrap()
602-
.parse()
603-
.unwrap();
598+
// Handle large numbers that would cause overflow
599+
let num_str = std::str::from_utf8(&rest[*index..(*index + i)]).unwrap();
604600
*index += i;
605-
Some(parsed)
601+
Some(num_str.parse().unwrap_or(usize::MAX))
606602
}
607603
}
608604
}

tests/by-util/test_printf.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,3 +1482,13 @@ fn test_large_width_format() {
14821482
.stdout_is("");
14831483
}
14841484
}
1485+
1486+
#[test]
1487+
fn test_extreme_field_width_overflow() {
1488+
// Test the specific case that was causing panic due to integer overflow
1489+
// in the field width parsing.
1490+
new_ucmd!()
1491+
.args(&["%999999999999999999999999d", "1"])
1492+
.fails_with_code(1)
1493+
.stderr_only("printf: write error\n");
1494+
}

0 commit comments

Comments
 (0)