Skip to content

Commit 0f246d5

Browse files
committed
dd: parse big numbers and return u64::MAX
Change the behavior of `dd` so that it parses numbers that would be too big and instead treats them as `u64::MAX`. This allows `dd` to run without error on dd count=00x9999999999999999999999999999999999999999999999999999999999999 This matches the behavior of GNU `dd`.
1 parent 3362d8a commit 0f246d5

File tree

2 files changed

+6
-11
lines changed

2 files changed

+6
-11
lines changed

src/uu/dd/src/parseargs.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ fn parse_bytes_only(s: &str) -> Result<u64, ParseError> {
490490
/// 512. You can also use standard block size suffixes like `'k'` for
491491
/// 1024.
492492
///
493+
/// If the number would be too large, return [`std::u64::MAX`] instead.
494+
///
493495
/// # Errors
494496
///
495497
/// If a number cannot be parsed or if the multiplication would cause
@@ -512,12 +514,10 @@ fn parse_bytes_no_x(full: &str, s: &str) -> Result<u64, ParseError> {
512514
let (num, multiplier) = match (s.find('c'), s.rfind('w'), s.rfind('b')) {
513515
(None, None, None) => match parser.parse_u64(s) {
514516
Ok(n) => (n, 1),
517+
Err(ParseSizeError::SizeTooBig(_)) => (u64::MAX, 1),
515518
Err(ParseSizeError::InvalidSuffix(_) | ParseSizeError::ParseFailure(_)) => {
516519
return Err(ParseError::InvalidNumber(full.to_string()))
517520
}
518-
Err(ParseSizeError::SizeTooBig(_)) => {
519-
return Err(ParseError::MultiplierStringOverflow(full.to_string()))
520-
}
521521
},
522522
(Some(i), None, None) => (parse_bytes_only(&s[..i])?, 1),
523523
(None, Some(i), None) => (parse_bytes_only(&s[..i])?, 2),
@@ -632,6 +632,8 @@ mod tests {
632632

633633
use crate::parseargs::parse_bytes_with_opt_multiplier;
634634

635+
const BIG: &str = "9999999999999999999999999999999999999999999999999999999999999";
636+
635637
#[test]
636638
fn test_parse_bytes_with_opt_multiplier() {
637639
assert_eq!(parse_bytes_with_opt_multiplier("123").unwrap(), 123);
@@ -641,6 +643,7 @@ mod tests {
641643
assert_eq!(parse_bytes_with_opt_multiplier("123x3").unwrap(), 123 * 3);
642644
assert_eq!(parse_bytes_with_opt_multiplier("123k").unwrap(), 123 * 1024);
643645
assert_eq!(parse_bytes_with_opt_multiplier("1x2x3").unwrap(), 6); // 1 * 2 * 3
646+
assert_eq!(parse_bytes_with_opt_multiplier(BIG).unwrap(), u64::MAX);
644647

645648
assert_eq!(
646649
parse_bytes_with_opt_multiplier("1wx2cx3w").unwrap(),

src/uu/dd/src/parseargs/unit_tests.rs

-8
Original file line numberDiff line numberDiff line change
@@ -506,14 +506,6 @@ mod test_64bit_arch {
506506
);
507507
}
508508

509-
#[test]
510-
#[should_panic]
511-
fn test_overflow_panic() {
512-
let bs_str = format!("{}KiB", u64::MAX);
513-
514-
parse_bytes_with_opt_multiplier(&bs_str).unwrap();
515-
}
516-
517509
#[test]
518510
#[should_panic]
519511
fn test_neg_panic() {

0 commit comments

Comments
 (0)