Skip to content

fix(core): compare relative paths longer than 512 bytes - #862

Open
kevin9327 wants to merge 1 commit into
dmtrKovalenko:mainfrom
kevin9327:fix/relative-path-eq-long-paths
Open

fix(core): compare relative paths longer than 512 bytes#862
kevin9327 wants to merge 1 commit into
dmtrKovalenko:mainfrom
kevin9327:fix/relative-path-eq-long-paths

Conversation

@kevin9327

@kevin9327 kevin9327 commented Sep 9, 2026

Copy link
Copy Markdown

The defect

FileItem::relative_path_eq reads the stored path into a [0u8; 512] scratch
buffer. ChunkedString::read_to_buf documents that it "Truncates at buf.len()
if exceeded -- use [u8; PATH_BUF_SIZE] to avoid", so for any relative path
longer than 512 bytes the comparison sees a 512-byte prefix, the lengths no
longer match, and the function returns false for a path compared against
itself
.

relative_path_starts_with, immediately below it in the same impl, already
uses [0u8; PATH_BUF_SIZE]. This is the one call site that kept the old size.

test_resolve_ptrs_path_exceeding_512_bytes (added with the resolve_ptrs fix)
makes the rule explicit for the same limit:

Truncation is not acceptable either: it silently drops the tail of the path
(including the filename here) from fuzzy matching.

Why it matters

relative_path_eq has two callers:

  • FilePickerSyncData::find_file_index — the linear scan over the overflow
    region, i.e. the lookup for every file the watcher appended after the initial
    scan. It backs handle_create_or_modify, remove_file_by_path,
    get_file_by_path and update_single_file_frecency. A watcher-added file
    whose relative path exceeds 512 bytes is never found, so a modify appends a
    second entry instead of updating the existing one, and a delete never
    tombstones it.
  • calculate_current_file_penalty — the current buffer stops being penalised,
    so the file you are already in keeps ranking first.

PATH_BUF_SIZE is PATH_MAX (and 4096 on Windows), so these paths are legal
and reachable in deeply nested trees.

The fix

Use PATH_BUF_SIZE, matching relative_path_starts_with. The length check
above it short-circuits before the buffer is created, so the larger array is
only built for a candidate that already has the right length.

Verification (Windows, default ripgrep features)

RUSTUP_TOOLCHAIN was pinned to 1.98.0-x86_64-pc-windows-msvc because
rust-toolchain.toml's stable channel could not update on this machine.

New test test_relative_path_eq_path_exceeding_512_bytes reuses the >512-byte
path from the neighbouring resolve_ptrs regression test.

Before, cargo test -p fff-search --lib -- simd_path:

test simd_path::tests::test_relative_path_eq_path_exceeding_512_bytes ... FAILED

---- simd_path::tests::test_relative_path_eq_path_exceeding_512_bytes stdout ----

thread 'simd_path::tests::test_relative_path_eq_path_exceeding_512_bytes' (6108) panicked at crates\fff-core\src\simd_path.rs:541:9:
a PATH_MAX-legal path must compare equal to itself

test result: FAILED. 14 passed; 1 failed; 0 ignored; 0 measured; 145 filtered out

After:

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 145 filtered out

The same test pins the short-path behaviour that must not change — src/lib.rs
still equals itself, still differs from src/main.rs, and the long path still
differs from a one-byte-shorter prefix of itself. Those three assertions pass
both before and after, so nothing is widened.

  • cargo test -p fff-search --lib — 160 passed, 0 failed.
  • cargo fmt --all -- --check — clean.
  • cargo clippy -p fff-search --lib — no new warnings (the three that fire
    under the default ripgrep features are in path_utils.rs and
    file_picker.rs, untouched here).

Summary by CodeRabbit

  • Bug Fixes

    • Improved file path comparisons for paths longer than 512 bytes.
    • Preserved accurate comparisons for shorter paths and correctly rejects truncated paths.
  • Tests

    • Added coverage for long relative paths to help prevent regressions.

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: db0b6bd9-fe6f-46a4-87e9-9590c1e80e66

📥 Commits

Reviewing files that changed from the base of the PR and between 7f8537e and 796eb67.

📒 Files selected for processing (2)
  • crates/fff-core/src/simd_path.rs
  • crates/fff-core/src/types.rs

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

relative_path_eq now supports paths longer than 512 bytes by using PATH_BUF_SIZE. A regression test validates long-path equality, short-path equality, and rejection of truncated paths.

Changes

Relative path comparison

Layer / File(s) Summary
Expand comparison buffer and validate long paths
crates/fff-core/src/types.rs, crates/fff-core/src/simd_path.rs
relative_path_eq uses PATH_BUF_SIZE. Tests cover paths exceeding 512 bytes and existing short-path behavior.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 796eb

Relative paths longer than 512 bytes now compare correctly within the supported buffer limit, preserving short-path behavior and rejecting truncated paths. No current merge-blocking risk is identified.

Suggested reviewers: dmtrkovalenko

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: comparing relative paths longer than 512 bytes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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