Skip to content

find: don't panic on invalid-UTF-8 arguments - #817

Open
MsfPablo wants to merge 2 commits into
uutils:mainfrom
MsfPablo:fix-printf-invalid-utf8-panic
Open

find: don't panic on invalid-UTF-8 arguments#817
MsfPablo wants to merge 2 commits into
uutils:mainfrom
MsfPablo:fix-printf-invalid-utf8-panic

Conversation

@MsfPablo

@MsfPablo MsfPablo commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

find used std::env::args(), which panics if any argument is not
valid UTF-8:

$ find d -printf $'%\xff|\n'
thread 'main' panicked at ...: called `Result::unwrap()` on an `Err` value
$ echo $?
101

The panic happens during argument collection, before the -printf
format parser is ever reached.

This switches to std::env::args_os() and reports invalid UTF-8 as a
normal error (exit 1) instead of panicking:

$ find d -printf $'%\xff|\n'
find: invalid UTF-8 was found in one of the arguments: %�|
$ echo $?
1

Full binary/byte passthrough (matching GNU find's behavior of
accepting arbitrary bytes) would need find_main and the whole
argument-parsing pipeline to switch from &str to OsStr, which is
a 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

  • Added find_printf_invalid_utf8_format_does_not_panic integration test
  • cargo test — 226 + 60 + ... all passing (full suite green)
  • cargo fmt --check clean
  • Manually reproduced the original panic and confirmed the fix

Fixes #816

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

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.94%. Comparing base (1f19cdd) to head (4dabff7).
⚠️ Report is 1 commits behind head on main.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Commit 5fe6fe6 has test result changes:

bfs testsuite:

Test results comparison:
  Current:   TOTAL: 314 / PASSED: 267 / FAILED: 41 / SKIPPED: 6
  Reference: TOTAL: 312 / PASSED: 266 / FAILED: 40 / SKIPPED: 6

Changes from main branch:
  TOTAL: +2
  PASSED: +1
  FAILED: +1

New test failures (1):
  - gnu/okdir_path_empty

@codspeed-hq

codspeed-hq Bot commented Aug 7, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 12.52%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 19 untouched benchmarks

Performance Changes

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)

Open in CodSpeed

Comment thread src/find/main.rs Outdated
"find: invalid UTF-8 was found in one of the arguments: {}",
invalid.to_string_lossy()
);
std::process::exit(1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.
@MsfPablo

MsfPablo commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

You're right — thanks. GNU find treats this as a warning and exits 0, not 1. Fixed in 4dabff7: main now lossy-converts the arg and continues (preserving the warning), instead of std::process::exit(1), so the exit code reflects only real errors like file-not-found.

Lossy-converting the -printf format then exposed a separate, pre-existing panic in the printf parser: FormatStringParser::advance_one byte-sliced self.string[1..] to drop the character it had just read, which panics whenever that character is multibyte — a lossy replacement char from invalid UTF-8, but also any non-ASCII char following a %-directive (e.g. find -printf '%€'). Fixed by slicing self.string[c.len_utf8()..] so one character is dropped rather than one byte.

Verified locally: cargo build, cargo test --test test_find (60 passed), cargo clippy clean. The test now expects success (exit 0) plus the warning, matching GNU.

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.

-printf panics on an invalid-UTF-8 format string (exit 101)

2 participants