Stop replace-all from destroying non-UTF-8 files - #62
Merged
Conversation
readFile 은 방금 고쳤는데 replaceInFiles 에 같은 자리가 그대로 남아 있었다. fs.readFile(abs, "utf8") 로 읽어 치환하고 도로 쓴다. 이쪽이 더 위험하다. 사용자가 열어 보지도 않은 파일을 프로젝트 전체로 훑으며 쓰기 때문이다. 실제 앱에서 재현했다 — CP949 로 된 legacy.c 에서 "int" 를 "long" 으로 한 번 바꿨더니 26바이트가 39바이트가 되고 한글 주석이 전부 U+FFFD 로 바뀌었다. 그러고도 "2개 파일 · 3곳 변경" 성공 토스트가 떴다. UTF-16 파일은 NUL 검사에 걸려 살아남았지만, 살아남았다는 말도 없었다. encoding.detect 로 걸러 건드리지 않고, 건너뛴 파일 목록을 skipped 로 돌려준다. 렌더러는 그 목록을 토스트로 띄운다 — 조용히 빼면 "전부 바꿨다" 로 읽히고, 그 파일들만 옛 이름이 남아 나중에 빌드가 깨진 뒤에야 알게 된다. BOM 붙은 UTF-8 파일은 그대로 치환되고 BOM 도 남는 것을 함께 확인했다. 실제 앱 검증 5/5 (고치기 전 3/5), 단위 954개 통과.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #61.
readFilewas fixed there;replaceInFileshad the identical line and was missed.The bug
schutz:replaceInFilesread every candidate withfs.readFile(abs, "utf8"), substituted, and wrote the result back. Non-UTF-8 bytes decode to U+FFFD and get written to disk.This is worse than the
readFilecase: replace-all sweeps files the user never opened, so the destruction is invisible.Reproduced in the real app — one
int→longreplace across a folder:legacy.c(CP949 Korean)utf16.txtThe toast said
2 files · 3 changes. Success.The fix
Filter with
encoding.detectand return the skipped files asskipped: string[]; the renderer surfaces them in a toast. Dropping them silently reads as "everything was replaced" — the user finds out when the build breaks in the one file that kept the old name.Verified alongside that a UTF-8-with-BOM file still gets replaced and keeps its BOM.
Verification
npm run typecheckclean.main.cjsline endings unchanged (1880 CRLF / 0 LF).The renderer-side guards on this path (blocks on unsaved buffers, reads
error/partial) were checked by reading and were already correct.