Found by an adversarial review during the Rust-migration wrap-up. Pre-existing (inherited from the Go implementation), so it is filed rather than fixed inline.
src/fixer.rs::fix_text rebuilds the file from text.lines() joined with \n plus a forced trailing newline. That silently normalises bytes the fixer never claimed to touch:
- CRLF input becomes LF wholesale. A 3-line CRLF file comes back all-LF while reporting "1 fixes applied".
- A file with no trailing newline gains one, reported as "0 fixes applied, 0 unfixable".
- An empty file becomes a single
\n, also reported as "0 fixes applied, 0 unfixable" -- macbash mutated the file while saying it did nothing.
The third is the worst: "0 fixes applied" should mean zero bytes changed.
Suggested fix
Preserve the original line ending and the original trailing-newline state: detect the dominant terminator on read, rejoin with it, and only append a final newline if the input had one. Short-circuit entirely when fixed_count == 0 -- if nothing was fixed, write nothing (or copy the input verbatim for the -o case).
Test to add
-w on CRLF / no-trailing-newline / empty input changes only the lines it claims to fix.
Found by an adversarial review during the Rust-migration wrap-up. Pre-existing (inherited from the Go implementation), so it is filed rather than fixed inline.
src/fixer.rs::fix_textrebuilds the file fromtext.lines()joined with\nplus a forced trailing newline. That silently normalises bytes the fixer never claimed to touch:\n, also reported as "0 fixes applied, 0 unfixable" -- macbash mutated the file while saying it did nothing.The third is the worst: "0 fixes applied" should mean zero bytes changed.
Suggested fix
Preserve the original line ending and the original trailing-newline state: detect the dominant terminator on read, rejoin with it, and only append a final newline if the input had one. Short-circuit entirely when
fixed_count == 0-- if nothing was fixed, write nothing (or copy the input verbatim for the-ocase).Test to add
-won CRLF / no-trailing-newline / empty input changes only the lines it claims to fix.