Skip to content

Commit b86f614

Browse files
committed
printf: Format String Parsing Overflow Causes Panic
1 parent 2000af8 commit b86f614

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -595,14 +595,19 @@ 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();
604-
*index += i;
605-
Some(parsed)
598+
// Handle large numbers that would cause overflow
599+
let num_str = std::str::from_utf8(&rest[*index..(*index + i)]).unwrap();
600+
match num_str.parse::<usize>() {
601+
Ok(parsed) => {
602+
*index += i;
603+
Some(parsed)
604+
}
605+
Err(_) => {
606+
// For overflow or other parse errors, use usize::MAX as a reasonable limit
607+
*index += i;
608+
Some(usize::MAX)
609+
}
610+
}
606611
}
607612
}
608613
}

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)