티스토리 뷰

프로그래밍/hwp

HWP 5.X파일의 구조.

쉬피드 2021. 8. 1. 21:20
728x90
반응형

HWP 5.0

HWP포맷은 3.X 버전부터 공개되어있지만 사실상 3.X 문서는 현재 거의 쓰이지 않고 있기에 해당 포맷은 분석하지 않는다.
우선 HWP포맷은 복합 파일 이진 형식(Compound File Binary Format) 이하 CFB라 불리는 파일의 포맷을 사용한다.

한컴문서

해당 포맷을 열어보는 프로그램은 이미 인터넷 검색만 해도 손 쉽게 나와있으며, 자바스크립트, 자바, 파이썬 등의 언어에서도 찾아볼 수 있다.
한컴에서 공개한 공식 문서에서 가장 핵심은 바로 이 내용이다.

분석

Image

위의 이미지에서도 확인할 수 있듯 zlib의 압축까지 풀어내야만 정확히 hwp포맷의 자료를 읽을 수 있다.
CFB, zlib 둘 다 공개되어있는 오픈소스이다보니 왠만한 메이저 프로그래밍 언어라면 손 쉽게 관련 플러그인이나 라이브러리를 찾아볼 수 있다.

여하튼 위의 두가지의 툴을 활용하여 열게 되면,

한글 문서는 DocInfo에 담긴 정보와 BodyText에 담긴 정보로 문서정보를 저장하고 출력하고 있는 것을 알 수 있다.

Image

Image

우선 DOC_INFO보다는 BodyText가 좀 더 핵심 정보이니 해당 부분부터 살펴보겠다.

HWPTAG_PARA_HEADER

모든 객체의 헤더 부분이다.
어떠한 객체든 간에 해당 헤더 부분은 필수적으로 들어가다보니, 대부분의 객체의 시작이라고 할 수 있다.(특정한 상황에서는 Tag ID가 선행되는 경우가 있으나 공식문서에서는 설명이 없어서 어려운 부분이 있다)

Image

헤더는 공식문서의 내용처럼 헤더에 정보를 얻고 있는데, 문제는 값이 명확하지 않은경우가 있다

우선 control mask가 무엇에 정확히 사용되는것인지 언급이 없는것 같다
단순히 못 찾는 걸수도 있지만..
또한 text는 해당 객체의 텍스트 길이를 나타내는데, 이 텍스트 길이가 어떤때는 정확하게 나타나지만 어떤때는 정확하게 나타나지 않는다.
읽는데에는 문제가 없지만 말이다.
Image

위의 그림처럼(text 필드 참조)가 오버플로우 되는것을 알 수 있다.
instance_id도 마찬가지인데, 해당 부분이 객체의 고유 아이디값처럼 보이지만..

2021년 8월 3일 수정
아래의 조건문을 반영하지 않았음. 반영하면 제대로 됨. 사이즈 크기가 아닌 글자 숫자가 나옴 한글로 이루어진 4글자라면 한글이 글자당 2바이트라서 텍스트 길이는 4로 나오고 아래의 PARA_TEXT 사이즈는 8이 된다.

우선 편집이 아닌 뷰어만을 만들기에 해당 아이디값이 크게 중요하진 않지만 무언가 찝찝한것은 사실이다.

HWPTAG_PARA_TEXT

실질적인 텍스트값이 들어가는 tag_id이다.

Image

아직 해당 텍스트 부분은 분석이 끝나지 않아서 간단하게 언급하고 넘어간다.
사실 HEADER에서 언급한 text 길이만큼 PARA_TEXT를 가변값을 얻을 수 있으나, 위에서 언급한것처럼 text길이가 제대로 나오지 않는 현상이 있다.

다만
Image
hwp포맷의 데이터 레코드 구조는 위를 따르고 있는데, 다음 4바이트 값에서 위의 레코드 구조를 읽으면 필드가 끝난 후 사이즈만큼 이동해주면 다음 tag_id값을 얻어낼 수 있고 이떄의 size와 헤더의 번호가 PARA_TEXT인 것 중 사이즈 값을 가져오면 정확하게 해당 PARA_TEXT길이를 가져올 수 있다.

해당 버퍼 구조만큼 계속 읽어와 문자를 utf-16le로 읽어오면 한글로 변환할 수 있다.

문서의 첫 TEXT는 경우 32바이트 크기만큼 무언가를 동작을 하고 해당 데이터를 읽어 보면 cold secd등 ctrl_id값이 들어가 있는 것을 알 수 있으나 정확히 무엇을 하는지, 어떤 역할인지 알기 어렵다.

그리고 그냥 넘기고 읽어도 크게 문제가 없는것 같다.

Image

그렇게 해서 읽으면 위와 같이 읽을 수 있고 각각의 문단(개행이 없는) 텍스트를 읽어 올 수 있다.

HWPTAG_PARA_LINE_SEG

이 부분이 개인적으론 골 때렸다
해당 옵션은 위의 문단의 높이, 넓이, 크기, 위치 등을 저장해놓는 것이다.
사실 레이아웃에서 해당 필드가 가장 기본이자 뿌리가 되는 거라 볼 수 있는데.. 문제가 많다.

Image
가변이라 언급되어있지만,
Image

공식문서의 테이블을 보면 가변이 아니다.
며칠간의 삽질끝에 알아냈는데,
문단이 텍스트 길이로 인해 개행되어 여러 줄이 되면 그 줄 수 만큼 사이즈가 커진다

4줄이면 36 x 4이다.

그리고 문제점 하나가 더 있는데 필드에서, 실질적으로 페이지의 시작. 첫줄, 등 여러가지 디테일한 정보가 들어있어야 한다.
텍스트 시작 위치부터 세그먼트의 폭까지는 정확한 값을 표시하나
그 뒤의 BIT로 저장된 태그값은 제대로 나오지 않는다.
전부 0으로 나오며 페이지 구분이나 테이블 내의 속성 등 여러가지 속성을 전혀 알 수 가 없다.
실제 한글 편집기에서는 해당 속성들이 존재하고, 제대로 동작하는것으로 보아 어딘가 어느곳에 어떻게든 있는 정보로 보이지만, 알기 매우 어렵다.
페이지의 첫행인지 아닌지는 여러가지 편법을 사용해야 한다.

2021년 8월 3일 수정. 작업자의 실수로 4바이트를 읽어야 하는데 2바이트를 읽고 값을 반영했었음.
다만, 페이지 첫줄값은 여전히 나오지 않는다. 정확히 어떤 값이 누락 되고 어떤값이 제대로 나오는지 알 수 없지만 현재는 들여쓰기값은 제대로 표시가 되는것으로 보임.

HWPTAG_PARA_LINE_SEG 다음부터는 다음 글에 작성하도록 하겠다.

728x90

'프로그래밍 > hwp' 카테고리의 다른 글

HWPTAG_FOOTNOTE_SHAPE 문서 오류  (0) 2022.05.02
HWP Header DOCINFO STYLE 누락 부분  (0) 2022.05.02
hwp MissingNo.  (0) 2021.08.25
hwpjs 웹뷰어.  (0) 2021.08.12
hwp 포맷 분석과 웹 뷰어 만들기  (0) 2021.07.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함