Skip to content

fix(hwp5,layout): give a negative cell height the cell's top and bottom margins - #465

Merged
airmang merged 5 commits into
mainfrom
fix/hwp5-negative-cell-height
Oct 16, 2026
Merged

airmang merged 5 commits into
mainfrom
fix/hwp5-negative-cell-height

Conversation

@airmang

@airmang airmang commented Oct 15, 2026

Copy link
Copy Markdown
Owner

바뀐 점

표 칸에는 높이가 음수로 든 것이 있다(파일에는 부호 없는 32비트로 남는다, -633이면 4294966663). 이런 .hwp를 열면 그 값을 hp:cellSz에 그대로 썼고, 쪽 수 추정과 배치 검사가 40억이 넘는 높이의 칸으로 읽어 .hwp를 바꾼 문서의 쪽 수가 수만 쪽으로 나왔다. 한/글은 그 칸을 위·아래 여백 높이(칸 자체 여백이 있으면 그것, 없으면 표 안 여백)로 놓고 글에 맞게 키운다. .hwp를 HWPX로 바꿀 때도, HWPX를 읽을 때도 같다.

  • src/hwpx/hwp5/section_xml.py: 표의 안 여백을 cell()로 넘기고, 음수 칸 높이는 그 칸의 위·아래 여백 합으로 쓴다.
  • src/hwpx/layout/pages.py: _cell_height — 음수로 남은 칸 높이를 없는 높이로 센다(칸 높이 = 여백 + 내용).
  • src/hwpx/layout/lint.py: 행 높이 계산에서 같은 규칙.
  • CHANGELOG.md: [Unreleased] 고침에 두 항목.

테스트

  • tests/fixtures/hwp5/cell_height_negative.hwp, cell_height_negative_own_margins.hwp: 3×2 표의 2행 1열 칸 높이가 -633(표 안 여백), -1000(칸 자체 여백 위 300·아래 500)인 .hwp. 한/글은 이를 HWPX로 바꿀 때 그 칸 높이를 282, 800으로 쓴다. 열었을 때 같은 값인지 본다.
  • tests/fixtures/hancom_saved/pages_cell_height_negative.hwpx: 음수 높이 칸을 한/글이 282로 놓고 저장한 1쪽 문서. 그 칸을 음수 높이로 다시 써도 쪽 수 추정이 1쪽인지(캐시 있음·없음) 본다.
  • 새 시험은 고치기 전 main에서 실패한다. ruff·mypy·pyright 통과, 전체 시험은 main과 같은 결과.

🤖 Generated with Claude Code

…om margins

A table cell may hold a negative height, kept as an unsigned 32-bit
number (-633 as 4294966663). Opening such a .hwp wrote that number to
hp:cellSz as is, and the page estimate and the layout lint read it as a
cell four billion units tall, so a converted document came out tens of
thousands of pages long. Hancom gives the cell the height of its top and
bottom margins (its own when it has them, else the table's inner ones)
and grows it to fit its text, both when it converts the .hwp and when
it reads the HWPX. The converter now writes that height, and the
estimate and the lint count a negative stored height as none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@airmang airmang left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

34a9a8d 검토 완료. HWP 표/칸 자체 여백 선택과 음수 칸 높이의 변환, 쪽 수 추정과 배치 검사에 같은 규칙 적용를 검토했고, 이 변경에서 재현된 코드 결함은 찾지 못했습니다. 별도 Python 3.12 체크아웃의 관련 회귀 테스트 1472개가 모두 통과했고 해당 head의 GitHub 검사 13개도 모두 성공했습니다. 다만 #462/#463 병합 후 최신 main dd67a530bf656a1deb38c1192937a755a49346d0과 병합하면 CHANGELOG.md에서 내용 충돌이 발생합니다(GitHub DIRTY/CONFLICTING 및 git merge-tree로 확인). 예약 작업의 병합 조건에 따라 이번에는 보류합니다. main을 merge해 양쪽 변경 기록을 유지하고 충돌을 해결한 뒤 최신 head의 검사를 다시 통과시키면 재검토할 수 있습니다.

@airmang airmang left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음수 셀 높이를 셀 자체 또는 표 안 여백으로 정규화하는 HWP 변환과 배치 검사 경로를 검토했습니다. 충돌은 양쪽 기록과 테스트를 보존해 해결했고, 재배치 전후 함수·데코레이터·데이터의 의미가 같음을 대조했습니다. Python 3.10–3.14 전체 CI, CodeQL, 의존성 검사가 모두 성공했습니다. 같은 커밋의 중복 PR 테스트 실행은 취소하고 push 매트릭스 성공을 확인했습니다. 최종 통합본의 관련 테스트 1,692개도 통과했습니다. 검토한 head를 지정하여 squash 병합합니다.

@airmang
airmang merged commit f0b084e into main Oct 16, 2026
8 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant