diff --git a/src/find/matchers/mod.rs b/src/find/matchers/mod.rs index e35ebbbb..c583b19b 100644 --- a/src/find/matchers/mod.rs +++ b/src/find/matchers/mod.rs @@ -308,8 +308,11 @@ fn convert_arg_to_number( option_name: &str, value_as_string: &str, ) -> Result> { + // Only accept plain decimal digits. Rust's `usize::from_str` also accepts a + // leading '+', but GNU find rejects a signed value like "+1" here, which is + // consistent with the "positive decimal integer" wording below. match value_as_string.parse::() { - Ok(val) => Ok(val), + Ok(val) if value_as_string.bytes().all(|b| b.is_ascii_digit()) => Ok(val), _ => Err(From::from(format!( "Expected a positive decimal integer argument to {option_name}, but got \ `{value_as_string}'" @@ -1790,6 +1793,18 @@ mod tests { } } + #[test] + fn convert_arg_to_number_test() { + assert_eq!(convert_arg_to_number("-maxdepth", "12").unwrap(), 12); + assert_eq!(convert_arg_to_number("-maxdepth", "0").unwrap(), 0); + // A signed value is rejected, matching GNU find (Rust's parser would + // otherwise accept the leading '+'). + assert!(convert_arg_to_number("-maxdepth", "+1").is_err()); + assert!(convert_arg_to_number("-mindepth", "+2").is_err()); + assert!(convert_arg_to_number("-maxdepth", "-1").is_err()); + assert!(convert_arg_to_number("-maxdepth", "1a").is_err()); + } + #[test] fn convert_arg_to_comparable_value_test() { assert_eq!(