fix(hwpx): hp:offset 음수 방출을 u32 wraparound 부호화로 바로잡는다 (#3544) - #3722
Open
kevin9327 wants to merge 1 commit into
Open
fix(hwpx): hp:offset 음수 방출을 u32 wraparound 부호화로 바로잡는다 (#3544)#3722kevin9327 wants to merge 1 commit into
kevin9327 wants to merge 1 commit into
Conversation
OWPML XSD 상 hp:offset 의 x/y 는 unsigned 인데, 재저장 시 `x="-8974"`, `y="-2"` 같은 음수가 기록되어 스키마를 위반했다(edwardkim#3544). 근인은 인코딩 비대칭이다. 한컴은 음수 오프셋을 u32 wraparound 십진수로 기록하고(-2429 → "4294964867") 파서도 `parse_u32 as i32` 로 같은 관례를 복호하는데, 저장기에는 대응하는 부호화가 없어 IR 의 signed 값을 그대로 문자열화했다. 클램프가 아니라 부호화 복원으로 고친다 — 클램프였다면 한컴이 기록한 음수 오프셋 정보가 소실되어 그룹 내부 좌표가 틀어진다. IR 이 i32 인 것은 레이아웃 계산상 정당하므로 XML 경계에서만 역함수를 적용한다. samples/hwpx 81종 재저장 기준 위반 64건 → 0건, 원본은 본래 0건. export-hwpx --verify 81/81 통과로 값이 아닌 표기만 바뀌었음을 확인했다. 자체 왕복 --verify 는 파서가 음수도 관대하게 읽어 이 버그를 잡지 못하므로, 신규 테스트는 방출된 XML 문자열 자체를 계약으로 고정하고 음수 0건과 wraparound 값 보존을 함께 단언해 향후 0 클램프 회귀도 막는다. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jangster77
self-requested a review
August 1, 2026 14:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
#3544— HWPX 재저장 시 OWPML 스키마상 unsigned 인<hp:offset>의x/y에음수가 기록되던 문제를 고칩니다. 저장기의
write_offset한 곳을 고쳐samples/hwpx81종 재저장 기준 위반 64건 → 0건이 됩니다.Fixes #3544
근인 — 클램프 문제가 아니라 인코딩 비대칭
이슈에서 미확인으로 남겨 두신 "음수가 생성되는 지점"을 특정했습니다. 음수는
레이아웃이 잘못 계산한 값이 아니라, 한컴이 의도적으로 쓴 값을 rhwp 가 잘못된
표기로 되돌려 쓴 것이었습니다.
한컴은 음수 오프셋을 u32 wraparound 십진수로 기록합니다(예:
-2429→"4294964867"). rhwp 파서도 같은 관례로 복호합니다.즉 복호(파서)는 있는데 대응하는 부호화(저장기)가 없었습니다.
write_offset이IR 의 signed 값을 그대로
to_string()한 탓에, 파서가4294964867→-2429로읽어들인 값이 저장 때
-2429문자열로 나가 XSD 를 위반했습니다.그래서 0 클램프가 아니라 부호화 복원으로 고쳤습니다. 클램프였다면 한컴이 기록한
음수 오프셋 정보가 소실되어 그룹 내부 좌표가 틀어집니다. IR 이
i32인 것은 레이아웃계산상 정당하므로 IR 은 그대로 두고, XML 경계에서만 파서 복호의 역함수를 적용합니다.
변경
src/serializer/hwpx/shape.rs의write_offset:같은
hp:offset을 쓰는src/serializer/hwpx/picture.rs는 IR 필드가HwpUnit = u32라 음수를 방출할 수 없음을 확인했습니다 — 수정 지점은 이 한 곳뿐입니다.검증
red → green
수정 블록을 되돌린 상태에서 신규 테스트가 실제로 실패함을 먼저 확인했습니다.
tests/issue_3544_hwpx_unsigned_offset.rs(실물 코퍼스)hp:offset16건 방출serializer::hwpx::shape::tests::issue3544_…(단위)x="-8974" y="-2"코퍼스 실측 (samples/hwpx 81종)
수정 전 64건은 이슈에 보고된 건수(64건)와 일치합니다.
회귀
cargo test --profile release-test --lib— 3016 passed, 0 failedrhwp export-hwpx <각 샘플> --verify— 81/81 통과 (IR 왕복 동일).값이 아니라 표기만 바뀌었음을 뒷받침합니다.
rustfmt --check(변경 파일),cargo clippy --profile release-test --bin rhwp -- -D warnings— 통과시각 검증
N/A. XML 속성의 어휘 표기만 바뀌고 디코드 결과 정수값은 동일합니다(
--verify81/81 로 IR 왕복 동일 확인). 렌더 경로에 입력되는 좌표가 변하지 않아 렌더 산출물
비교 대상이 없습니다.
테스트 설계 노트
자체 왕복
--verify는 이 버그를 잡지 못합니다 — rhwp 파서가 음수 표기도 관대하게읽어 IR 이 왕복상 일치해 버리기 때문입니다(수정 전에도
--verify는 exit 0). 그래서신규 테스트는 IR 이 아니라 방출된 XML 문자열 자체를 계약으로 고정하고, 두 가지를
함께 단언해 향후 "0 클램프" 류 회귀도 막습니다.
hp:offset에 음수 십진수가 0건일 것 (XSD unsigned)남은 범위
이번 수정은 이슈가 제시한
hp:offset계열을 닫습니다. 다른 unsigned 좌표 속성에같은 인코딩 비대칭이 있는지는 위 코퍼스 검증 범위 밖이며, 발견되면 별도 이슈로
다루는 편이 변경 범위를 좁게 유지한다고 판단했습니다.
처리결과 문서:
mydocs/report/pr-hwpx-unsigned-offset.md🤖 Generated with Claude Code