find: don't panic on invalid-UTF-8 arguments - #817
Conversation
std::env::args() panics if any argument is not valid UTF-8, so a non-UTF-8 -printf format string (or any other argument) crashed find with exit code 101 instead of a normal error. Collect args via env::args_os() instead and report invalid UTF-8 as a regular error (exit 1) rather than panicking. Fixes uutils#816
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #817 +/- ##
==========================================
+ Coverage 91.93% 91.94% +0.01%
==========================================
Files 35 35
Lines 7251 7261 +10
Branches 378 378
==========================================
+ Hits 6666 6676 +10
Misses 443 443
Partials 142 142 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Commit 5fe6fe6 has test result changes: bfs testsuite: |
Merging this PR will improve performance by 12.52%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ⚡ | printf |
36.9 ms | 32.8 ms | +12.52% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing MsfPablo:fix-printf-invalid-utf8-panic (4dabff7) with main (065320c)
| "find: invalid UTF-8 was found in one of the arguments: {}", | ||
| invalid.to_string_lossy() | ||
| ); | ||
| std::process::exit(1); |
There was a problem hiding this comment.
that is a warning in GNU findutils, thus exits with 0
Match GNU find, which treats an invalid-UTF-8 argument as a warning and continues with a lossy conversion (exit 0) rather than aborting with exit 1. Replaces the hard std::process::exit(1) in main with a lossy conversion that preserves the existing warning. Lossy-converting the -printf format exposes a pre-existing panic in FormatStringParser::advance_one: it byte-sliced self.string[1..] to drop the just-read character, which panics whenever that character is multibyte (a lossy replacement char from invalid UTF-8, or any non-ASCII char following a %-directive). Slice by c.len_utf8() instead so one character is dropped. Test now expects success (exit 0) + the warning, matching GNU.
|
You're right — thanks. GNU find treats this as a warning and exits 0, not 1. Fixed in 4dabff7: Lossy-converting the Verified locally: |
Summary
findusedstd::env::args(), which panics if any argument is notvalid UTF-8:
The panic happens during argument collection, before the
-printfformat parser is ever reached.
This switches to
std::env::args_os()and reports invalid UTF-8 as anormal error (exit 1) instead of panicking:
Full binary/byte passthrough (matching GNU find's behavior of
accepting arbitrary bytes) would need
find_mainand the wholeargument-parsing pipeline to switch from
&strtoOsStr, which isa much larger refactor — happy to look into that separately if
maintainers want it, but this fixes the immediate panic/exit-101 bug
with a minimal change.
Test plan
find_printf_invalid_utf8_format_does_not_panicintegration testcargo test— 226 + 60 + ... all passing (full suite green)cargo fmt --checkcleanFixes #816