diff --git a/src/find/matchers/mod.rs b/src/find/matchers/mod.rs index 1a2cc68a..d8d4c018 100644 --- a/src/find/matchers/mod.rs +++ b/src/find/matchers/mod.rs @@ -307,8 +307,10 @@ 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. 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}'" diff --git a/tests/test_find.rs b/tests/test_find.rs index 26f9a6d8..fe294bb0 100644 --- a/tests/test_find.rs +++ b/tests/test_find.rs @@ -157,6 +157,18 @@ fn size_rejects_non_numeric_prefix() { } } +#[test] +fn depth_rejects_signed_value() { + // A signed depth like "+1" is rejected, matching GNU find. + for opt in ["-maxdepth", "-mindepth"] { + ucmd() + .args(&["./test_data", opt, "+1"]) + .fails() + .stderr_contains("positive decimal integer argument"); + ucmd().args(&["./test_data", opt, "1"]).succeeds(); + } +} + #[test] fn multiple_matcher_failure() { ucmd()