Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed — one document is the same bytes in both editors (2026-10-01)

- JSON and `.flow` loads join equal-format neighbouring runs, as the HTML and RTF readers already did and as the port
does: a file split one line into any number of runs, and the same content now loads as the same model.
- Colours are written `#AARRGGBB` in upper case, as the format states and the port writes. `Color.ToString()` wrote a
known colour's NAME (`"Red"`) and anything else in lower case. Every reader takes either.
- `Alt` and `VAlign` are written where the port writes them (field order is the written order).
- `tests/…/Fixtures/format-1.0-interchange.json` uses every field in the canonical form. The port holds the same file
and the same test — read it, write it back, byte for byte — so a change to what either editor writes fails in the
repository that made it.

### Changed — the JSON writer leaves out what every reader assumes (2026-10-01)

**The schema is unchanged** (still `"1.0"`), and every reader since 1.0 reads the new output exactly as before —
checked directly: the tree before this change read 18 documents written the new way (the fixpoint set and corpus
pages) and produced, byte for byte, what it produces from its own output, as JSON and as `.flow`.

- Fields equal to the value a reader assumes when they are absent are not written: a run's `Bold`/`Italic`/
`Underline`/`Strikethrough` false and `FontSize` 10, a paragraph's `HeadingLevel`, `ListLevel`, `Indent`, `IsQuote`,
`MarginRight`, `ListType` `None`, `TextAlignment` `Left`, each block kind's own default bottom margin, `Type`
`Paragraph`/`Run`, a table's `Rows`/`Columns` (readers rebuild them) and its span grids when nothing is merged.
The legacy `IsListItem` — documented as never written — had been written on every paragraph.
- **Non-ASCII text is written as it is.** Korean went out as `정보…`, six bytes a character and unreadable
in a diff. Characters HTML is sensitive to (`< > & ' "`) are still escaped, so the JSON can be embedded in a page.
- **Not indented.** Indentation was half of every document.
- Measured on `tests/corpus`: 240.6 → 37.7 KB, 3,043 → 378 KB; the kitchen-sink document 15.9 → 1.3 KB. A `.flow`
package changes little on disk (its `document.json` was already deflated).
- ⚠ **Hosts that compare saved JSON byte for byte** (snapshot tests) will see the new form.

Also:
- **A newer major format is refused** by `LoadJson`, `LoadJsonAsync` and `LoadPackageAsync` (`JsonException`, like a
damaged file): it would come in with what this reader does not know turned into empty paragraphs, and a save would
write that over the file. `DocumentSerializer.Deserialize` stays lenient. An unknown block or inline `Type` within
the same major is read as text and reported to `RichEditorDiagnostics`.
- A paragraph whose `MarginTop` a host set to `Block.AutoTopMargin` (NaN) threw on save — JSON has no NaN.
- `docs/DOCUMENT_FORMAT.md` caught up with the code: damaged input throws (it said "empty document"), the default page
margin is 15 mm (it said 12.7/10.6), an absent `MarginTop` on a table, picture or divider is automatic (it said 0),
and the round-35 import bounds.

### Fixed — round 35: a full audit; the size and depth of untrusted input (2026-10-01)

Every source file was read. Most of what turned up is one axis earlier rounds never measured: how LARGE and how
Expand Down
6 changes: 6 additions & 0 deletions Project_Roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ PR #48·#49·#50), 실기 후속도 PR #52로 들어왔다. 남은 것은 게시
게시 절차: `<Version>` → Unshipped를 Shipped로 이관 → CHANGELOG `[Unreleased]` → 버전 → README 배지(en/ko) → PR로 3-OS CI →
`v1.3.0` 태그 push(**사람이 실행**, Trusted Publishing) → **nuget.org 패키지 페이지 육안 확인**.

**1b. JSON 작성기 경량화 (2026-10-01)** — 스키마 그대로, 작성기만: 기본값 필드 생략·한글 비이스케이프·들여쓰기 없음.
corpus 240.6 → 37.7 KB, 3,043 → 378 KB. **구 판독기 호환은 구 트리로 직접 확인**(18개 문서, JSON·.flow 바이트 동일).
메이저 버전이 더 높은 문서는 로드 경로가 거부, 모르는 `Type`은 진단 보고. 명세(`docs/DOCUMENT_FORMAT.md`)의 어긋남도 정정.
사용자 결정: 들여쓰기 옵션 없이 제거, 메이저 거부 도입. 포트도 같은 형식이라 같이 옮길 것.
포트 대조(라운드35)는 끝났다 — WinUIRichEditor PR #62(14건 백포트, 상류 픽셀 상한은 포트에 불필요).

**1a. 라운드35 · 전수 감사 (2026-10-01, PR #59 머지)** — `src` 약 19,500줄을 모델 → 포매터 → 컨트롤 순으로 읽었다. 결함 **16건**
(프로세스 종료 3·데이터 소실 3·보안 1), 전부 빨강 먼저 → 수정 → 개별 반증. 대부분 이전 라운드가 재지 않은 **입력의 크기·깊이** 축이다. 테스트: `Round35AuditTests`.
- 치명(프로세스 종료, catch 불가): HTML `<div>` 2,000겹(11 KB) 붙여넣기, 중첩 표 400단(RTF `\itap` 무제한) 렌더 — 스택 오버플로.
Expand Down
Loading
Loading