text 생성과 markdown 생성 기능을 추가합니다.#237
Conversation
Release v0.7.2: VS Code 컨텍스트 메뉴 + 한컴 단축키 + 커맨드 팔레트 + 양식 컨트롤
Release v0.7.2: npm 패키지 배포 준비 — @rhwp/core + @rhwp/editor + VS Code 0.7.2
Windows 환경에서 cfb 크레이트 동작 시 발생하는 역슬래시(\) 경로 구분자 문제를 슬래시(/) 단위로 일일이 변경하여 모든 OS 환경에서 일관된 경로를 보장하도록 함.
Problem ------- HwpxReader::read_file and read_file_bytes called read_to_string / read_to_end directly on zip::ZipFile readers with no size ceiling. ZIP allows extreme compression ratios, so a few-KB .hwpx can claim a single section.xml entry that expands to multi-GB — OOMing the host. Any downstream (CLI, WASM, browser extension, VS Code) inherits the risk since all of them funnel through parse_hwpx → HwpxReader. Fix --- Introduce a small read_limited(reader, max) helper using Read::take so we never allocate past max+1 bytes. Apply: - MAX_XML_SIZE = 32 MB for text entries (section/header/hpf) - MAX_BINDATA_SIZE = 64 MB for binary entries (images, fonts) Real-world Korean government HWPX (보도자료·법령·판례) stays well under these, so legitimate files are unaffected. Over-limit entries surface as HwpxError::ZipError with "decompression bomb" in the message — callers see a clean parse error instead of a crash. Rationale for thresholds ------------------------ MDM (https://github.com/seunghan91/markdown-media) has been running the same 32/64 MB caps in production across ~500 real HWPX fixtures with zero false positives; see MDM commit a94b459 for the original application of this pattern across HWP/HWPX/PDF parser paths. Tests ----- Five unit tests in parser::hwpx::reader: - under / at / over cap boundary for read_limited - a synthetic zip-bomb entry (MAX_XML_SIZE + 1 bytes of 'A', compressed to <1 MB) is rejected with ZipError Full suite: 789 passed, 0 failed (baseline + 5 new). No public API change: HwpxError variants unchanged, method signatures unchanged. MAX_XML_SIZE / MAX_BINDATA_SIZE are exposed as pub const so integrators can read the current caps. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Problem
-------
parser/hwpx/header.rs:293 treats any shape != "NONE" | "3D" as a real
strikethrough:
cs.strikethrough = !matches!(val.as_str(), "NONE" | "3D");
This is a blacklist of known placeholders. It is correct for the 3D
case Hancom emits today, but fails open: any future placeholder value
Hancom adds (e.g. "4D", "Ghost", internal experiments) will be
misinterpreted as a real strike line, and entire body-text paragraphs
will render with strikethrough.
Fix
---
Flip the predicate to a whitelist of OWPML LineSym2 values that shape.rs
already recognises (SOLID, DASH, DOT, DASH_DOT, DASH_DOT_DOT, LONG_DASH,
CIRCLE, DOUBLE_SLIM, SLIM_THICK, THICK_SLIM, SLIM_THICK_SLIM, WAVE,
DOUBLE_WAVE — 13 entries, same set as the enum mapping immediately
below). Unknown values — including NONE, 3D, and any future Hancom
placeholder — are fail-closed to no-strike.
Extracted into a `pub(crate) fn is_real_strike_shape(&str) -> bool`
so the predicate is independently testable and can be reused if other
parsers (e.g. underline, which has the same blacklist risk) adopt the
same approach later.
Evidence
--------
MDM (https://github.com/seunghan91/markdown-media) hit the exact same
bug earlier this month. Hancom's HWPX exporter writes <hh:strikeout
shape="3D"/> as a placeholder default on body-text charPr definitions.
Treating "anything but NONE" as strike caused press-release bodies
(e.g. "251113 벤처투자 보도자료") to render wrapped in ~~...~~.
Our fix (MDM commit ae15dd8) moved to the whitelist approach and
verified across 21 MOIS HWPX fixtures: zero false strikes remained.
The same logic fits rhwp one-for-one, so we're upstreaming it.
Tests
-----
Five new unit tests in parser::hwpx::header::tests:
- all 13 valid OWPML LineSym2 shapes → true
- "NONE" → false
- "3D" → false (the original bug)
- fail-closed cases: "4D", "Ghost", "", "solid" (case-sensitive)
Full suite: 789 passed, 0 failed.
No behaviour change for files Hancom currently emits — the set of
shapes that produce strike=true is identical to the old blacklist
path for every value shape.rs knows about. The only difference is
forward-compatibility: unknown future placeholders no longer get
mis-rendered as strike.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eparator fix(parser): Windows 환경의 CFB 경로 구분자 오류 수정
…otection fix(hwpx): cap ZIP entry decompression to defeat zip bombs
…-whitelist refactor(hwpx): whitelist strikeout shapes instead of blacklist
Release v0.7.3 (라이브러리) / v0.2.0 (확장)
Hotfix v0.2.1 (확장): 매뉴얼 §5.1 누락 버전 보강
라이브러리/확장 이원화 정책에 따라 버전 표기 정리: - 라이브러리 v0.7.3 (Cargo, npm/core, npm/editor, vscode, studio) - 확장 v0.2.1 (chrome, safari) — Chrome Web Store / Edge Add-ons 심사 진행 중 문서 갱신: - README.md / README_EN.md / rhwp-chrome/README.md: 변경 이력 + 향후 예정 + 외부 기여자 6명 누적 명시 - mydocs/orders/20260419.md: v0.2.1 표기로 일관성 정리 - mydocs/plans/task_m100_196.md, working/stage3, report: v0.2.1 표기 스토어 등록 정보 (mydocs/feedback/, mydocs/release/): - kor_desc_0.2.1.md, eng_desc_0.2.1.md: 한국어/영어 마켓 설명 (HWPX 베타 안내 + 기여자 + PR 번호) - cert_notes_0.2.1.md: 심사용 Notes for certification (1986 chars) - add_desc_02.md: 변경 사항 추가용 텍스트 - release_notes_v0.7.3.md: GitHub Release 노트 다음 사이클: v0.7.5 통일 (라이브러리 + 확장 단일 버전 정책) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs + CodeQL fix: v0.7.3 회고 보고서 + build.mjs alert edwardkim#16 fix
2026-04-21 oosmetrics.com 독창성(originality) 지표에서 rhwp 가 WebAssembly · Editors 두 카테고리 Top 2 달성. - README.md · README_EN.md 상단에 별도 줄로 성과 배지 2개 추가 - 기술 배지(CI/Demo/npm/VSCode/License/Rust/WASM) 와 시각 분리 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
한글판 README.md 와 영문판 README_EN.md 의 섹션 구조·내용을 1:1 일치시킴. 주요 변경: - Roadmap + Milestones 섹션을 상단(로드맵/이정표 위치) 으로 이동 - v0.5.0 ~ v0.7.x 이정표에 v0.2.1 사이클 전체 반영 (Chrome/Edge 심사 통과, PR edwardkim#213/edwardkim#215/edwardkim#221/edwardkim#169/edwardkim#209/edwardkim#214/edwardkim#224/edwardkim#181) - rhwp-firefox (v0.1.1 AMO 준비) + rhwp-safari (v0.2.1) 섹션 추가 - 기여자 감사 목록 확장: @seo-rii, @planet6897, @yl-star7 추가 (9명) - Features: OLE/Chart/EMF native rendering 항목 추가 (edwardkim#221) - Project Structure: src/emf/, src/ooxml_chart/, rhwp-firefox/, rhwp-shared/ 반영 - Trademark 섹션 신규 (한글판 동일 위치) - AI 페어 프로그래밍 섹션: Git Workflow / Task Workflow / Debugging Protocol / Documentation Rules 완전 반영 - 로드맵 링크를 mydocs/eng/report/rhwp-milestone.md 로 보정 - 테스트 수치 783 → 935 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
특정 상용 제품 기여 의사 전달을 계기로, 프로젝트 문서의 경쟁 비교 · 성능 비교 · 렌더링 분석 문맥에서 해당 제품명을 일반화 표현으로 교체. 변경 원칙: - A (사용자 인용, report/x_hwp_viewer_voices.md): 원문 보존, 건드리지 않음 - B (프로젝트 문서 비교·주장): "일부 상용 제품" / "a commercial web office" / "일부 상용 웹오피스" - C (archives 포함): "경쟁사" → "일부 상용 제품" 적용 - D (영문판): 한글판과 동일하게 동시 수정 대상 파일 (21): - mydocs/tech/: project_vision, webgian_replacement_strategy, canvas_rendering_analysis, font_metrics_size_comparison, incremental_relayout_design, direct_printing_guideline - mydocs/manual/hyper_waterfall_docs_guide.md - mydocs/plans/archives/: task_124, task_126 - mydocs/working/archives/: task_123_report, task_125_step1234_done - mydocs/eng/ 영문판 10개 (한글판 1:1 대응) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
main에서 devel로 잘 못 병합 요청 되었습니다. |
안녕하세요 🙏@nameofSEOKWONHONG 님, 이미 상황을 인지하시고 정중하게 알려주셔서 감사합니다. 말씀하신 대로 처리 도와드리겠습니다. 먼저 꼭 말씀드리고 싶은 것기능 자체는 정말 환영하는 기여입니다:
이 두 기능은 rhwp를 AI 파이프라인의 입력으로 쓸 때 반드시 필요한 기능입니다. Claude/GPT에 HWP 내용을 전달하거나, HWP 문서를 블로그/위키에 통합할 때 곧바로 활용됩니다. 제가 보기엔 rhwp의 출력 채널을 한 단계 확장하는 귀중한 기여입니다. 현재 PR 처리말씀하신 대로 이번 PR은 close하겠습니다. base를 재제출 시 참고해주세요Fork에서 작업하실 때 도움이 될 만한 체크리스트입니다: 1. Fork를 최신 upstream과 동기화 # upstream 등록 (최초 1회)
git remote add upstream https://github.com/edwardkim/rhwp.git
git fetch upstream
# Fork의 main을 upstream/main과 맞춤
git checkout main
git merge upstream/main
git push origin main
# 작업은 upstream/devel 기준으로 — feature 브랜치 생성
git checkout upstream/devel
git checkout -b feature/export-text-markdown2. 본인 작업만 담은 커밋 이번 PR에는 이미 merge된 다른 PR의 커밋(#134, #135, #152, #153, #154, #200, #201, #203 등)이 17개나 포함되어 diff가 커졌습니다. 깨끗한 feature 브랜치에서 작업하시면 본인 커밋만 1~3개로 정리됩니다. 3. base는 PR 생성 시 반드시 4. Clippy 미통과 체크리스트에 5. 관련 이슈 등록 (권장) rhwp는 Hyper-Waterfall 방법론에 따라 Issue 등록 → 수행·구현 계획서 → 구현 → PR 순서를 따릅니다. 재제출 전에: gh issue create --repo edwardkim/rhwp \
--title "export-text / export-markdown CLI 명령 추가" \
--body "HWP 문서를 텍스트/마크다운으로 내보내는 CLI 명령..." \
--milestone "v1.0.0"PR body의 기다리고 있겠습니다이 기능 정말 필요한 기여입니다. 재제출해주시면 꼼꼼하게 리뷰해드리겠습니다. 혹시 재작업 과정에서 막히시는 부분이 있으면 언제든 코멘트 남겨주세요. 🙏 감사합니다. — 메인테이너 드림 |
|
요청대로 close 처리합니다. devel 대상 새 PR로 재제출 부탁드립니다. 감사합니다! 🙏 |
- mydocs/pr/archives/pr_237_review.md: base 브랜치 오류 분석 (Fork main → upstream devel) - mydocs/pr/archives/pr_237_report.md: 작성자 자진 취소 + 정중한 close, 재제출 가이드 기여자 @nameofSEOKWONHONG 의 export-text/export-markdown 기능은 환영 기여. PR 구조 정리 후 재제출 대기.
기여자 @planet6897 이 PR #235에 포함해 제출한 기존 섹션(Task #229 Fix / #240)은 그대로 보존하고, 오늘의 메인테이너 활동을 별도 섹션으로 추가: - PR #234 (close, 재제출 요청) / #235 (merge) / #237 (작성자 자진 취소) 처리 요약 - mydocs/pr/ 폴더 체계 신설 + CLAUDE.md/CONTRIBUTING.md 규칙 보완 - 트러블슈팅 hwp_letter_spacing_compensation.md 추가 - Task #157 시작 (재현 확인, LAYOUT_OVERFLOW 4건 관측)
작성자 산출물의 보고서 내부 링크가 feature_*.md 패턴이었으나 실제 파일명은 task_m100_237*.md 로 작성됨. 메인테이너 측에서 링크 정정. A2 (page_count == 0 가드) 는 작성자가 본인 PR 본문에서 "미구현" 이라 자가 보고했으나 실제 코드 (src/main.rs:545, 665) 에는 이미 early return 가드가 있어 underflow 발생 가능성 없음 — 추가 수정 불필요. closes edwardkim#237 Co-Authored-By: SEOKWON HONG <nameofSEOKWONHONG@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rkdown Task #237: export text, markdown 구현
@nameofSEOKWONHONG 의 PR 인수 (작업지시자 결정 — 작성자 응답 3d+). cherry-pick + A1 보강 (보고서 링크) + admin merge (commit da55552). A2 (page_count == 0 가드) 는 점검 결과 이미 정상 (early return) — 추가 수정 불필요. Co-Authored-By: SEOKWON HONG <nameofSEOKWONHONG@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
변경 요약
text 생성과 markdown 생성 기능을 추가합니다.
관련 이슈
closes #
테스트
cargo test통과cargo clippy -- -D warnings통과스크린샷