Skip to content

Fix 23 file ops, search, batch, and user menu bugs#50

Merged
leszek3737 merged 3 commits into
mainfrom
fix44
May 19, 2026
Merged

Fix 23 file ops, search, batch, and user menu bugs#50
leszek3737 merged 3 commits into
mainfrom
fix44

Conversation

@leszek3737

@leszek3737 leszek3737 commented May 19, 2026

Copy link
Copy Markdown
Owner

Greptile Summary

This PR addresses 23 reported bugs across file operations, batch processing, search, and the user menu. The fixes cover a broad surface area including TOCTOU hardening, symlink-aware deduplication, wildcard matcher replacement, option-injection protection, and fail-closed condition semantics.

  • file_ops.rs: Copy operations now use a temp-then-rename pattern with post-copy symlink-race revalidation; delete_dir_recursive uses Path-based critical-dir comparison instead of string-prefix matching; publish_temp_dir now takes source permissions rather than reading them from the temp dir.
  • batch.rs: dedup_paths switches from canonicalize-based dedup to inode identity (dev+ino) so symlinks and their targets are kept as distinct entries; the destination dedup key is canonicalized before insertion.
  • search.rs: DP wildcard matcher replaced with a greedy algorithm; needle_str stored to avoid per-match allocation; WildcardSimple gains a combined prefix+suffix length guard; several functions made pub.
  • user_menu.rs: Invalid/unsupported conditions now compile to CompiledCondition::Never (fail-closed); safe_file_arg prepends -- for dash-leading filenames; current_file field widened to &Path to handle non-UTF-8 names consistently.

Confidence Score: 3/5

Two copy paths leave temporary files/directories on disk when specific error conditions are hit, and the new cross-platform dedup code will fail to compile on Windows due to unconditional declarations only consumed inside unix-only cfg blocks.

The temp-file leak in copy_file (apply_metadata failure path) and the temp-dir leak in both copy_dir_recursive variants (canonicalize failure inside the Ok arm) are real, reachable error paths that leave filesystem garbage behind. The unused seen_ids and meta bindings on non-Unix will produce compiler warnings that become hard errors under RUSTFLAGS=-D warnings, breaking Windows builds. These three issues are independent and affect different parts of the change.

src/ops/file_ops.rs (temp-resource cleanup paths) and src/ops/batch.rs (non-Unix cfg hygiene) need the most attention before merging.

Important Files Changed

Filename Overview
src/ops/file_ops.rs Large set of copy/delete hardening changes; introduces two temp-resource leaks (apply_metadata failure in copy_file, and canonicalize failure inside the Ok arm of both copy_dir_recursive variants) and a backup-file collision risk on Windows in swap_temp_to_dest.
src/ops/batch.rs Rewrites dedup_paths to use inode identity instead of canonicalize; seen_ids and meta are declared/bound unconditionally but only used inside #[cfg(unix)], causing unused-variable warnings/errors on non-Unix. Dest dedup key canonicalization fix looks correct.
src/app/user_menu.rs Adds safe_file_arg to prepend -- before dash-leading filenames, changes invalid/unsupported conditions to CompiledCondition::Never, and fixes body-line stripping. Changes look correct; documented limitations are appropriate.
src/ops/search.rs Replaces DP wildcard matcher with greedy algorithm, adds needle_str to avoid per-match allocation, makes several functions pub, adds non-UTF-8 line error reporting, and adds early-exit length check for WildcardSimple. No issues found.
src/ops/helpers.rs Renames path_starts_with to lexical_path_starts_with and improves entry-error logging in dir_size_rec. Clean rename, no issues.
src/ops/sorting.rs Moves inline comment to a doc comment on sort_entries. Documentation-only change.
src/input/pickers.rs Updates SubstContext construction to wrap current_file string as Path::new, tracking the API change in user_menu.rs. Trivial adaptation.
src/ops/mod.rs Changes search module visibility from pub(crate) to pub. Intentional API exposure.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[copy_file / copy_dir_recursive] --> B[reserve_temp_file/dir]
    B --> C[copy content to temp]
    C --> D{copy succeeded?}
    D -- No --> E[cleanup_file/dir_all\nreturn Err]
    D -- Yes --> F[apply_metadata to temp]
    F --> G{metadata applied?}
    G -- No --> H[temp LEAKED - missing cleanup_file]
    G -- Yes --> I{dest.exists? / revalidate dest}
    I -- dest changed --> J[cleanup_file/dir_all\nreturn Err]
    I -- dest OK --> K{canonicalize_with_nearest... ?}
    K -- Err --> L[temp_dest LEAKED - missing cleanup_dir_all]
    K -- Ok --> M[publish_temp_dir / swap_temp_to_dest]
    M --> N{rename succeeded?}
    N -- No --> O[cleanup_file/dir_all\nreturn Err]
    N -- Yes --> P[return Ok bytes]
Loading

file_ops.rs: no-op perms (7.1), Windows overwrite race (7.2), case-rename docs (7.3), TOCTOU copy (7.8), string prefix critical-dir check (7.9), symlink descendant race (7.10)
batch.rs: uncanonicalized dest dedup (7.4), symlink-aware dedup_paths (7.5)
helpers.rs: silent entry errors (7.6), rename path_starts_with → lexical_path_starts_with (7.7)
search.rs: glob overlap false positive (8.1), silent non-UTF-8 skip (8.2), missing pub API (8.3), İ limitation doc (8.4), per-match alloc (8.7), DP→greedy wildcard matcher (8.8)
user_menu.rs: fail-open conditions (9.1), whitespace stripping (9.2), %f non-UTF-8 inconsistency (9.3), option injection (9.4)
types.rs/README: CompareMode docs (8.5), dirs caveat (8.6)
sorting.rs: ASCII-only natural sort doc (8.9)

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leszek3737, you have reached your weekly rate limit of 1500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several improvements to file operations, path handling, and search functionality. Key changes include a more robust dedup_paths implementation using device/inode IDs, enhanced safety in file and directory copying through temporary files and symlink race detection, and a more efficient greedy wildcard matching algorithm. Feedback from the review highlights potential issues with the option injection prevention strategy in shell commands, a collision risk in the Windows file backup naming scheme, the need for better error reporting when backup restoration fails, and potential memory overhead from excessive error logging during file searches.

Comment thread src/app/user_menu.rs
Comment thread src/ops/file_ops.rs Outdated
Comment thread src/ops/file_ops.rs Outdated
Comment thread src/ops/search.rs Outdated
Comment thread src/ops/file_ops.rs Outdated
Comment thread src/ops/file_ops.rs Outdated
Comment thread src/ops/batch.rs
Comment thread src/ops/file_ops.rs Outdated
Repository owner deleted a comment from greptile-apps Bot May 19, 2026
@leszek3737
leszek3737 merged commit 94cab71 into main May 19, 2026
5 checks passed
@leszek3737
leszek3737 deleted the fix44 branch May 19, 2026 04:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant