From bf2d93f56379dd3c48865131c61e6b6f865692a5 Mon Sep 17 00:00:00 2001 From: MsfPablo Date: Sat, 8 Aug 2026 22:01:34 +0200 Subject: [PATCH] fix(find): -mindepth N -maxdepth M with N>M now matches nothing GNU/BSD find semantics: when -mindepth is greater than -maxdepth, no depth satisfies both bounds, so the walk should produce no output. Previously uutils find relied on walkdir's min_depth/max_depth setters, which silently clamp the contradiction (whichever is set last wins). Because process_dir set max_depth before min_depth, '-mindepth 2 -maxdepth 1' was clamped to min_depth=max_depth=1 and wrongly printed depth-1 entries. Add an explicit guard in process_dir that returns early (no output) when config.min_depth > config.max_depth, before constructing the walkdir builder. Fixes #778 --- src/find/mod.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/find/mod.rs b/src/find/mod.rs index f6b80751..58e1f9d1 100644 --- a/src/find/mod.rs +++ b/src/find/mod.rs @@ -211,6 +211,15 @@ fn process_dir( matcher: &dyn matchers::Matcher, quit: &mut bool, ) -> i32 { + // GNU/BSD find semantics: `-mindepth N -maxdepth M` with N > M matches no + // depth (none is simultaneously >= N and <= M), so the walk yields nothing. + // We must short-circuit here because walkdir's `min_depth`/`max_depth` + // setters silently clamp to resolve the contradiction (whichever is set last + // wins), which would instead surface entries at the smaller depth. See #778. + if config.min_depth > config.max_depth { + return 0; + } + let mut walkdir = WalkDir::new(dir) .contents_first(config.depth_first) .max_depth(config.max_depth) @@ -816,6 +825,51 @@ mod tests { ); } + #[test] + fn find_mindepth_greater_than_maxdepth() { + // `-mindepth N -maxdepth M` with N > M matches no depth, so GNU/BSD + // find print nothing. Regression test for #778: walkdir's setters + // silently clamp the contradiction, which previously surfaced entries + // at the smaller depth instead of nothing. + let deps = FakeDependencies::new(); + let rc = find_main( + &[ + "find", + &fix_up_slashes("./test_data/depth"), + "-sorted", + "-mindepth", + "2", + "-maxdepth", + "1", + ], + &deps, + ); + + assert_eq!(rc, 0); + assert_eq!(deps.get_output_as_string(), ""); + } + + #[test] + fn find_mindepth_greater_than_maxdepth_reversed_order() { + // The depth flags may be given in either order; both must yield nothing. + let deps = FakeDependencies::new(); + let rc = find_main( + &[ + "find", + &fix_up_slashes("./test_data/depth"), + "-sorted", + "-maxdepth", + "1", + "-mindepth", + "2", + ], + &deps, + ); + + assert_eq!(rc, 0); + assert_eq!(deps.get_output_as_string(), ""); + } + #[test] fn find_newer() { // create a temp directory and file that are newer than the static