Skip to content

Refuse to open non-UTF-8 files instead of destroying them - #61

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

Refuse to open non-UTF-8 files instead of destroying them#61
Seungpyo1007 merged 1 commit into
developfrom
fix/non-utf8-file-guard

Conversation

@Seungpyo1007

Copy link
Copy Markdown
Member

The bug

schutz:readFile was unconditionally fs.readFile(abs, "utf8"). Anything that is not UTF-8 comes back as U+FFFD replacement characters, and saving writes those replacements to disk. The original bytes are gone, with no undo.

Reproduced in the real app:

File Before
UTF-16LE (Notepad "Unicode") open + Ctrl+S alone: 16 bytes → 20 bytes
CP949 Korean (very common on Windows) shows as // �ȳ� ����; one edit + save destroys the whole file

The fix

electron/encoding.cjs is a pure decision — BOM check, NUL check, UTF-8 round-trip comparison — returning null when the bytes are safe, or why they are not (utf16le / utf16be / binary / not-utf8). readFile now reads bytes, asks, and refuses to open the file instead of handing back a mangled string.

The renderer maps the code to a translated message (4 languages) in the editor's error surface. Refusing without saying why just looks like a broken editor.

Reading other encodings is a feature; not silently destroying files is a prerequisite. This does the prerequisite.

Verification

  • Real-app probe (CDP): 7/7, was 2/5 before the fix.
  • Unit: 11 new tests for detect / errorFor / kindOf; 954 total passing.
  • npm run typecheck clean. main.cjs line endings unchanged (1873 CRLF / 0 LF).

readFile 이 무조건 fs.readFile(abs, "utf8") 이었다. UTF-8 이 아닌 파일은
디코딩에서 U+FFFD 로 바뀌고, 그 상태로 저장하면 원본이 사라진다. 되돌릴
방법이 없다.

재현했다. UTF-16 파일은 열고 Ctrl+S 만 눌러도 16바이트가 20바이트가 됐다.
CP949 로 저장된 한글 파일은 `// �ȳ� ����` 로 뜨고, 한 글자만 고쳐
저장하면 파일 전체가 사라진다. 윈도우에서 아주 흔한 인코딩이다.

electron/encoding.cjs 에 순수 판정을 두고(BOM·NUL·UTF-8 왕복 비교),
readFile 이 아니라고 판단하면 열지 않고 이유를 돌려준다. 렌더러는 그
코드를 4개국어 안내 문구로 바꿔 편집기 자리에 띄운다 — 왜 안 열리는지
말해 주지 않으면 그냥 고장 난 편집기로 보인다.

다른 인코딩을 읽어 주는 것은 기능이고, 조용히 부수지 않는 것은 그 전에
지켜야 할 일이다.

실제 앱 검증 7/7 (고치기 전 2/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 a4e7b8a into develop Aug 5, 2026
1 check passed
@Seungpyo1007
Seungpyo1007 deleted the fix/non-utf8-file-guard branch August 5, 2026 01:40
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