fix(fff-search): keep filename_offset on a char boundary for non-UTF-8 names - #805
fix(fff-search): keep filename_offset on a char boundary for non-UTF-8 names#805kevin9327 wants to merge 1 commit into
Conversation
…8 names
new_from_walk_bytes stored the caller's basename_offset, which indexes the raw
path bytes, as the filename_offset into a String produced by from_utf8_lossy.
For a name with invalid UTF-8 the lossy conversion replaces each ill-formed
byte with a 3-byte U+FFFD, shifting every later index, so the offset could land
inside a replacement char. Slicing the relative path there then panicked on the
Rayon scan thread and aborted the process:
end byte index N is not a char boundary; it is inside '\u{fffd}'
Re-derive the split from the lossy string when a byte was replaced (Cow::Owned),
matching what the pure-Rust walker path already does; valid UTF-8 keeps the fast
raw offset with no rfind. Adds a unit test.
Fixes dmtrKovalenko#799.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe file picker now recalculates basename offsets after lossy UTF-8 conversion. This prevents invalid string slicing for non-UTF-8 filenames. A regression test verifies correct directory and filename splitting. ChangesInvalid UTF-8 path handling
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This localized change prevents crashes when scanning filenames with invalid UTF-8 bytes, with no actionable merge-blocking risk remaining after normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Thank you for your fix but I made a slightly more efficient one here #809 |
Fixes #799.
The crash
Scanning a directory that contains a filename with invalid UTF-8 bytes aborts the process from the Rayon scan thread:
Root cause
FileItem::new_from_walk_bytes(the zlob walker fast path) is handed abasename_offsetthat indexes the raw path bytes, and stores it as thefilename_offsetinto aStringbuilt withString::from_utf8_lossy(relative_path).from_utf8_lossyreplaces each ill-formed byte with a 3-byteU+FFFD, so on a non-UTF-8 name every index past the first bad byte shifts. The stored offset can then point inside a replacement char, and the later&rel[..filename_offset]slice (and thesplit_atat line 2207) panics on the non-boundary index. TheSAFETY: filename_offset is always at a character boundarynote a few lines up does not hold for this path.The pure-Rust walker path (
new_from_walk) is unaffected because it derives the offset from the lossy string itself viarfind(is_separator).The fix
Re-derive the split from the lossy string when a byte was actually replaced (
Cow::Owned), the same way the walker path does. Valid UTF-8 is the overwhelming common case and stays on the fast path:from_utf8_lossyborrows, so the rawbasename_offsetis used unchanged with norfind.Verification (Windows, default
ripgrepfeatures)walk_bytes_offset_stays_on_a_char_boundary_for_non_utf8_names: feedsb"\xff/.txt"with the rawbasename_offset(2) that used to slice inside theU+FFFD, and asserts the split lands on a boundary ("\u{fffd}/"+".txt"). It panics onmain, passes here.cargo test -p fff-search --lib— 160 passed, 0 failed.cargo fmt --all -- --check— clean.The test drives
new_from_walk_bytesdirectly, so it exercises the fix under either glob backend.Summary by CodeRabbit