diff --git a/src/uu/factor/src/factor.rs b/src/uu/factor/src/factor.rs index d6fa4ba8c5..9ebabf9ef0 100644 --- a/src/uu/factor/src/factor.rs +++ b/src/uu/factor/src/factor.rs @@ -81,22 +81,25 @@ fn parse_num(slice: &[u8]) -> UResult { ) }; let num = str::from_utf8(slice).map_err(|_| err_invalid(&NumError(slice).to_string()))?; + // Only leading spaces are skipped; other whitespace makes the number invalid. + let digits = num.trim_start_matches(' '); - match num.parse::() { + match digits.parse::() { Ok(x) => return Ok(Number::U64(x)), // If overflown, attempt a greater width Err(e) if *e.kind() == IntErrorKind::PosOverflow => {} Err(_) => return Err(err_invalid(num)), } - match num.parse::() { + match digits.parse::() { Ok(x) => return Ok(Number::U128(x)), // If overflown, attempt a greater width Err(e) if *e.kind() == IntErrorKind::PosOverflow => {} Err(_) => return Err(err_invalid(num)), } - num.parse::() + digits + .parse::() .map(Number::BigUint) .map_err(|_| err_invalid(num)) } @@ -159,7 +162,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if let Some(values) = matches.get_many::(options::NUMBER) { for number in values { - write_factors_str(number.trim().as_bytes(), &mut w, print_exponents)?; + write_factors_str(number.as_bytes(), &mut w, print_exponents)?; } } else { let stdin = stdin(); diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index cbd1d31213..524745e9fc 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -58,6 +58,23 @@ fn test_repeated_exponents() { .no_stderr(); } +#[test] +fn test_argument_whitespace() { + new_ucmd!() + .args(&[" 30", " +7"]) + .succeeds() + .stdout_only("30: 2 3 5\n7: 7\n"); + new_ucmd!() + .args(&["30 ", " x"]) + .fails_with_code(1) + .no_stdout() + .stderr_is( + "factor: '30 ' is not a valid positive integer\n\ + factor: ' x' is not a valid positive integer\n", + ); + new_ucmd!().arg("\t30").fails_with_code(1).no_stdout(); +} + #[test] fn test_trim_null_chars() { new_ucmd!()