Merge pull request #5901 from jfinkels/dd-parse-big-numbers

dd: parse big numbers and return u64::MAX
This commit is contained in:
Sylvestre Ledru 2024-01-28 21:12:14 +01:00 committed by GitHub
commit 08f07f9bfd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 15 deletions

View file

@ -490,6 +490,8 @@ fn parse_bytes_only(s: &str) -> Result<u64, ParseError> {
/// 512. You can also use standard block size suffixes like `'k'` for /// 512. You can also use standard block size suffixes like `'k'` for
/// 1024. /// 1024.
/// ///
/// If the number would be too large, return [`std::u64::MAX`] instead.
///
/// # Errors /// # Errors
/// ///
/// If a number cannot be parsed or if the multiplication would cause /// 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> {
let (num, multiplier) = match (s.find('c'), s.rfind('w'), s.rfind('b')) { let (num, multiplier) = match (s.find('c'), s.rfind('w'), s.rfind('b')) {
(None, None, None) => match parser.parse_u64(s) { (None, None, None) => match parser.parse_u64(s) {
Ok(n) => (n, 1), Ok(n) => (n, 1),
Err(ParseSizeError::SizeTooBig(_)) => (u64::MAX, 1),
Err(ParseSizeError::InvalidSuffix(_) | ParseSizeError::ParseFailure(_)) => { Err(ParseSizeError::InvalidSuffix(_) | ParseSizeError::ParseFailure(_)) => {
return Err(ParseError::InvalidNumber(full.to_string())) return Err(ParseError::InvalidNumber(full.to_string()))
} }
Err(ParseSizeError::SizeTooBig(_)) => {
return Err(ParseError::MultiplierStringOverflow(full.to_string()))
}
}, },
(Some(i), None, None) => (parse_bytes_only(&s[..i])?, 1), (Some(i), None, None) => (parse_bytes_only(&s[..i])?, 1),
(None, Some(i), None) => (parse_bytes_only(&s[..i])?, 2), (None, Some(i), None) => (parse_bytes_only(&s[..i])?, 2),
@ -632,20 +632,30 @@ mod tests {
use crate::parseargs::parse_bytes_with_opt_multiplier; use crate::parseargs::parse_bytes_with_opt_multiplier;
const BIG: &str = "9999999999999999999999999999999999999999999999999999999999999";
#[test] #[test]
fn test_parse_bytes_with_opt_multiplier() { fn test_parse_bytes_with_opt_multiplier_invalid() {
assert!(parse_bytes_with_opt_multiplier("123asdf").is_err());
}
#[test]
fn test_parse_bytes_with_opt_multiplier_without_x() {
assert_eq!(parse_bytes_with_opt_multiplier("123").unwrap(), 123); assert_eq!(parse_bytes_with_opt_multiplier("123").unwrap(), 123);
assert_eq!(parse_bytes_with_opt_multiplier("123c").unwrap(), 123); // 123 * 1 assert_eq!(parse_bytes_with_opt_multiplier("123c").unwrap(), 123); // 123 * 1
assert_eq!(parse_bytes_with_opt_multiplier("123w").unwrap(), 123 * 2); assert_eq!(parse_bytes_with_opt_multiplier("123w").unwrap(), 123 * 2);
assert_eq!(parse_bytes_with_opt_multiplier("123b").unwrap(), 123 * 512); assert_eq!(parse_bytes_with_opt_multiplier("123b").unwrap(), 123 * 512);
assert_eq!(parse_bytes_with_opt_multiplier("123x3").unwrap(), 123 * 3);
assert_eq!(parse_bytes_with_opt_multiplier("123k").unwrap(), 123 * 1024); assert_eq!(parse_bytes_with_opt_multiplier("123k").unwrap(), 123 * 1024);
assert_eq!(parse_bytes_with_opt_multiplier("1x2x3").unwrap(), 6); // 1 * 2 * 3 assert_eq!(parse_bytes_with_opt_multiplier(BIG).unwrap(), u64::MAX);
}
#[test]
fn test_parse_bytes_with_opt_multiplier_with_x() {
assert_eq!(parse_bytes_with_opt_multiplier("123x3").unwrap(), 123 * 3);
assert_eq!(parse_bytes_with_opt_multiplier("1x2x3").unwrap(), 6); // 1 * 2 * 3
assert_eq!( assert_eq!(
parse_bytes_with_opt_multiplier("1wx2cx3w").unwrap(), parse_bytes_with_opt_multiplier("1wx2cx3w").unwrap(),
2 * 2 * (3 * 2) // (1 * 2) * (2 * 1) * (3 * 2) 2 * 2 * (3 * 2) // (1 * 2) * (2 * 1) * (3 * 2)
); );
assert!(parse_bytes_with_opt_multiplier("123asdf").is_err());
} }
} }

View file

@ -506,14 +506,6 @@ mod test_64bit_arch {
); );
} }
#[test]
#[should_panic]
fn test_overflow_panic() {
let bs_str = format!("{}KiB", u64::MAX);
parse_bytes_with_opt_multiplier(&bs_str).unwrap();
}
#[test] #[test]
#[should_panic] #[should_panic]
fn test_neg_panic() { fn test_neg_panic() {