Skip to content

Stop replace-all from destroying non-UTF-8 files - #62

Merged
Seungpyo1007 merged 1 commit into
developfrom
fix/replace-all-non-utf8
Aug 5, 2026
Merged

Stop replace-all from destroying non-UTF-8 files#62
Seungpyo1007 merged 1 commit into
developfrom
fix/replace-all-non-utf8

Conversation

@Seungpyo1007

Copy link
Copy Markdown
Member

Follow-up to #61. readFile was fixed there; replaceInFiles had the identical line and was missed.

The bug

schutz:replaceInFiles read every candidate with fs.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 readFile case: replace-all sweeps files the user never opened, so the destruction is invisible.

Reproduced in the real app — one intlong replace across a folder:

File Before After
legacy.c (CP949 Korean) 26 bytes 39 bytes, every Korean character replaced with U+FFFD
utf16.txt untouched (caught by the NUL check) untouched — but never reported

The toast said 2 files · 3 changes. Success.

The fix

Filter with encoding.detect and return the skipped files as skipped: 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

  • Real-app probe (CDP, via the actual IPC handler with the workspace open): 5/5, was 3/5 before.
  • Unit: 954 passing. npm run typecheck clean. main.cjs line 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.

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개 통과.
@Seungpyo1007 Seungpyo1007 added this to the v0.3 (2026-09-30) milestone Aug 5, 2026
@Seungpyo1007 Seungpyo1007 added the bug Something isn't working label Aug 5, 2026
@Seungpyo1007 Seungpyo1007 self-assigned this Aug 5, 2026
@Seungpyo1007
Seungpyo1007 merged commit c30de4e into develop Aug 5, 2026
1 check passed
@Seungpyo1007
Seungpyo1007 deleted the fix/replace-all-non-utf8 branch August 5, 2026 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant