Repository navigation
od: preserve non-UTF-8 file operands - #15242
ozenyunus35 wants to merge 3 commits into
Conversation
od collected its arguments with `collect_ignore()`, which silently drops every argument that is not valid UTF-8. Such a file operand was lost, so `od $'\xff'` read standard input (and hung on a terminal) instead of dumping the file or reporting that it does not exist. Pass the raw arguments to clap and keep file operands as `OsString` all the way to `File::open`. Offsets and labels are still parsed from operands that are valid UTF-8. Fixes uutils#12794
|
|
||
| let (at, mut ucmd) = at_and_ucmd!(); | ||
| let name = OsStr::from_bytes(b"\xff"); | ||
| std::fs::write(at.plus(name), "abcdefghijklmnopqrstuvwxyz\n").unwrap(); |
There was a problem hiding this comment.
Better to user at.write(file, content) here.
There was a problem hiding this comment.
Unless I'm missing something that doesn't work because name is an OsStr whereas at.write expects a &str.
There was a problem hiding this comment.
Ah yes indeed. Maybe we could update at.write to take and AsRef<Path> ?
There was a problem hiding this comment.
Thanks for opening #15287! Once it lands I'm happy to switch these tests over to at.write, either here or in a small follow-up.
|
The tests you added are broken in web-assembly, hence the CI fails. I suggest setting the tests' cfgs to #[cfg(not(any(target_os = "wasi", windows)))] |
wasmtime cannot pass an argument that is not valid UTF-8 to the utility, so these tests cannot run there. Mark them like the other tests that depend on non-UTF-8 arguments.
|
Thanks for the review! I updated the tests in 36237d8. I used the repository's existing Regarding |
| show_error!( | ||
| "{}: {}", | ||
| self.file_name.unwrap_or("I/O"), | ||
| self.file_name.map_or("I/O".into(), OsStr::to_string_lossy), |
There was a problem hiding this comment.
could use maybe_quote() here like the open error above, no?
| .pipe_in("not read") | ||
| .succeeds() | ||
| .stdout_only(unindent(ALPHA_OUT)); | ||
| } |
There was a problem hiding this comment.
could you please also add a test with an offset, e.g. od --traditional <non-utf8> 10?
|
@sylvestre done in 4482a3a: the read error now uses |
Merging this PR will degrade performance by 3.83%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | five_38_bit_primes |
1.7 s | 2.4 s | -31.25% |
| ❌ |
Simulation | sort_reverse_utf8_locale |
79.2 ms | 81.9 ms | -3.28% |
| ⚡ | Simulation | three_39_bit_primes |
490.4 ms | 366.6 ms | +33.79% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ozenyunus35:fix/od-non-utf8-operands (4482a3a) with main (efca981)2
Footnotes
-
54 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
-
No successful run was found on
main(d43f2b8) during the generation of this report, so efca981 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
Summary
Fixes #12794.
odcurrently drops command-line arguments that are not valid UTF-8. When such an argument is a filename,odbehaves as if no file was provided and falls back to reading standard input.This can cause
odto wait for input unexpectedly or read unrelated data instead of reporting a missing file.Changes
OsStringthroughout argument parsing and file handling.File::open.Testing
Added two regression tests:
The first test fails before the fix and passes afterward.
Validation performed on macOS:
test_od: 75 passed.uu_odunit tests: 55 passed.cargo fmt --check: passed.-D warnings: passed.The Linux-specific filesystem test could not be executed on macOS and will be exercised by Linux CI.
Compatibility
The change is limited to
odargument and file handling. Existing behavior for valid UTF-8 filenames, standard input, and offsets is preserved.AI Assistance
Claude Code was used to assist with implementation and testing.