diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index 1425cae01..028deab74 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -325,6 +325,14 @@ impl std::str::FromStr for StatusLevel { } } +fn show_zero_multiplier_warning() { + show_warning!( + "{} is a zero multiplier; use {} if that is intended", + "0x".quote(), + "00x".quote() + ); +} + /// Parse bytes using str::parse, then map error if needed. fn parse_bytes_only(s: &str) -> Result { s.parse() @@ -357,13 +365,6 @@ fn parse_bytes_only(s: &str) -> Result { /// assert_eq!(parse_bytes_no_x("2k").unwrap(), 2 * 1024); /// ``` fn parse_bytes_no_x(s: &str) -> Result { - if s == "0" { - show_warning!( - "{} is a zero multiplier; use {} if that is intended", - "0x".quote(), - "00x".quote() - ); - } let (num, multiplier) = match (s.find('c'), s.rfind('w'), s.rfind('b')) { (None, None, None) => match uucore::parse_size::parse_size(s) { Ok(n) => (n, 1), @@ -401,13 +402,20 @@ fn parse_bytes_with_opt_multiplier(s: &str) -> Result { // Split on the 'x' characters. Each component will be parsed // individually, then multiplied together. - let mut total = 1; - for part in s.split('x') { - let num = parse_bytes_no_x(part).map_err(|e| e.with_arg(s.to_string()))?; - total *= num; + let parts: Vec<&str> = s.split('x').collect(); + if parts.len() == 1 { + parse_bytes_no_x(parts[0]).map_err(|e| e.with_arg(s.to_string())) + } else { + let mut total = 1; + for part in parts { + if part == "0" { + show_zero_multiplier_warning(); + } + let num = parse_bytes_no_x(part).map_err(|e| e.with_arg(s.to_string()))?; + total *= num; + } + Ok(total) } - - Ok(total) } pub fn parse_ibs(matches: &Matches) -> Result { diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 58c577a7d..22daec60c 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -201,6 +201,13 @@ fn test_x_multiplier() { #[test] fn test_zero_multiplier_warning() { for arg in ["count", "seek", "skip"] { + new_ucmd!() + .args(&[format!("{}=0", arg).as_str(), "status=none"]) + .pipe_in("") + .succeeds() + .no_stdout() + .no_stderr(); + new_ucmd!() .args(&[format!("{}=00x1", arg).as_str(), "status=none"]) .pipe_in("") @@ -1063,3 +1070,12 @@ fn test_all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() { .succeeds() .stdout_is_fixture_bytes("all-valid-ascii-chars-37eff01866ba3f538421b30b7cbefcac.test"); } + +#[test] +fn test_skip_zero() { + new_ucmd!() + .args(&["skip=0", "status=noxfer"]) + .succeeds() + .no_stdout() + .stderr_is("0+0 records in\n0+0 records out\n"); +}