fix(core): compare relative paths longer than 512 bytes - #862
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthrough
ChangesRelative path comparison
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to 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: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
The defect
FileItem::relative_path_eqreads the stored path into a[0u8; 512]scratchbuffer.
ChunkedString::read_to_bufdocuments that it "Truncates atbuf.len()if exceeded -- use
[u8; PATH_BUF_SIZE]to avoid", so for any relative pathlonger than 512 bytes the comparison sees a 512-byte prefix, the lengths no
longer match, and the function returns
falsefor a path compared againstitself.
relative_path_starts_with, immediately below it in the sameimpl, alreadyuses
[0u8; PATH_BUF_SIZE]. This is the one call site that kept the old size.test_resolve_ptrs_path_exceeding_512_bytes(added with theresolve_ptrsfix)makes the rule explicit for the same limit:
Why it matters
relative_path_eqhas two callers:FilePickerSyncData::find_file_index— the linear scan over the overflowregion, 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_pathandupdate_single_file_frecency. A watcher-added filewhose 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_SIZEisPATH_MAX(and 4096 on Windows), so these paths are legaland reachable in deeply nested trees.
The fix
Use
PATH_BUF_SIZE, matchingrelative_path_starts_with. The length checkabove 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
ripgrepfeatures)RUSTUP_TOOLCHAINwas pinned to1.98.0-x86_64-pc-windows-msvcbecauserust-toolchain.toml'sstablechannel could not update on this machine.New test
test_relative_path_eq_path_exceeding_512_bytesreuses the >512-bytepath from the neighbouring
resolve_ptrsregression test.Before,
cargo test -p fff-search --lib -- simd_path:After:
The same test pins the short-path behaviour that must not change —
src/lib.rsstill equals itself, still differs from
src/main.rs, and the long path stilldiffers 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 fireunder the default
ripgrepfeatures are inpath_utils.rsandfile_picker.rs, untouched here).Summary by CodeRabbit
Bug Fixes
Tests