diff options
Diffstat (limited to 'hwpfilter/source/hwpread.cxx')
-rw-r--r-- | hwpfilter/source/hwpread.cxx | 930 |
1 files changed, 930 insertions, 0 deletions
diff --git a/hwpfilter/source/hwpread.cxx b/hwpfilter/source/hwpread.cxx new file mode 100644 index 000000000..a77f380b5 --- /dev/null +++ b/hwpfilter/source/hwpread.cxx @@ -0,0 +1,930 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "precompile.h" + +#include <comphelper/newarray.hxx> +#include <unotools/configmgr.hxx> +#include <tools/long.hxx> + +#include <assert.h> + +#include "hwpfile.h" +#include "hbox.h" +#include "hpara.h" +#include "drawing.h" +#include "htags.h" +#include "hcode.h" + +static short fboxnum = 1; +static int zindex = 1; +static int lnnumber = 0; + +bool HBox::Read(HWPFile & ) +{ + // already read + return true; +} + +// skip block +bool SkipData::Read(HWPFile & hwpf) +{ + uint data_block_len; + hwpf.Read4b(data_block_len); + + hchar dummy; + if (!hwpf.Read2b(dummy)) + return hwpf.SetState(HWP_InvalidFileFormat); + + if (!(IS_SP_SKIP_BLOCK(hh) && (hh == dummy))){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + + return hwpf.SkipBlock(data_block_len); +} + +// Field code(5) +bool FieldCode::Read(HWPFile & hwpf) +{ + uint size; + hchar dummy; + uint len1; /* Length of hchar type string DATA #1 */ + uint len2; /* Length of hchar type string DATA #2 */ + uint len3; /* Length of hchar type string DATA #3 */ + uint binlen; /* Length of any binary data format */ + + hwpf.Read4b(size); + if (!hwpf.Read2b(dummy)) + return false; + hwpf.ReadBlock(&type, 2); + hwpf.ReadBlock(reserved1.data(), 4); + if (!hwpf.Read2b(location_info)) + return false; + hwpf.ReadBlock(reserved2.data(), 22); + hwpf.Read4b(len1); + hwpf.Read4b(len2); + hwpf.Read4b(len3); + if (!hwpf.Read4b(binlen)) + return false; + + uint const len1_ = std::min<uint>(len1, 1024) / sizeof(hchar); + uint const len2_ = std::min<uint>(len2, 1024) / sizeof(hchar); + uint const len3_ = std::min<uint>(len3, 1024) / sizeof(hchar); + + str1.reset( new hchar[len1_ ? len1_ : 1] ); + str2.reset( new hchar[len2_ ? len2_ : 1] ); + str3.reset( new hchar[len3_ ? len3_ : 1] ); + + if (hwpf.Read2b(str1.get(), len1_) != len1_) + return false; + hwpf.SkipBlock(len1 - (len1_ * sizeof(hchar))); + str1[len1_ ? (len1_ - 1) : 0] = 0; + if (hwpf.Read2b(str2.get(), len2_) != len2_) + return false; + hwpf.SkipBlock(len2 - (len2_ * sizeof(hchar))); + str2[len2_ ? (len2_ - 1) : 0] = 0; + if (hwpf.Read2b(str3.get(), len3_) != len3_) + return false; + hwpf.SkipBlock(len3 - (len3_ * sizeof(hchar))); + str3[len3_ ? (len3_ - 1) : 0] = 0; + + hwpf.SkipBlock(binlen); + + if( type[0] == 3 && type[1] == 2 ){ /* It must create a format as created date. */ + DateCode *pDate = new DateCode; + for (uint i = 0 ; i < len3_; i++) { + if(str3[i] == 0 ) break; + if( i >= DATE_SIZE ) break; + pDate->format[i] = str3[i]; + } + hwpf.AddDateFormat(pDate); + m_pDate.reset( pDate ); + } + + return true; +} + +// book mark(6) +bool Bookmark::Read(HWPFile & hwpf) +{ + uint len; + + hwpf.Read4b(len); + if (!hwpf.Read2b(dummy)) + return false; + + if (len != 34)// 2 * (BMK_COMMENT_LEN + 1) + 2 + { + return hwpf.SetState(HWP_InvalidFileFormat); + } + if (hh != dummy || dummy != CH_BOOKMARK) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + + hwpf.Read2b(id, BMK_COMMENT_LEN + 1); + hwpf.Read2b(&type, 1); + return true; +} + +// date format(7) +bool DateFormat::Read(HWPFile & hwpf) +{ + hwpf.Read2b(format, DATE_SIZE); + if (!hwpf.Read2b(dummy)) + return false; + if (hh != dummy || CH_DATE_FORM != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + return true; +} + +// date code(8) +bool DateCode::Read(HWPFile & hwpf) +{ + hwpf.Read2b(format, DATE_SIZE); + hwpf.Read2b(date, 6); + if (!hwpf.Read2b(dummy)) + return false; + if (hh != dummy || CH_DATE_CODE != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + hwpf.AddDateFormat(this); + return true; +} + +// tab(9) +bool Tab::Read(HWPFile & hwpf) +{ + unsigned short tmp16; + if (!hwpf.Read2b(tmp16)) + return false; + width = tmp16; + if (!hwpf.Read2b(leader)) + return false; + if (!hwpf.Read2b(dummy)) + return false; + if (hh != dummy || CH_TAB != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + return true; +} + +// tbox(10) TABLE BOX MATH BUTTON HYPERTEXT +static void UpdateBBox(FBox * fbox) +{ + fbox->boundsy = fbox->pgy; + fbox->boundey = fbox->pgy + fbox->ys - 1; +} + +bool Cell::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&p, 1); + hwpf.Read2b(&color, 1); + hwpf.Read2b(&x, 1); + hwpf.Read2b(&y, 1); + hwpf.Read2b(&w, 1); + hwpf.Read2b(&h, 1); + hwpf.Read2b(&txthigh, 1); + hwpf.Read2b(&cellhigh, 1); + + hwpf.Read1b(flag); + hwpf.Read1b(changed); + hwpf.Read1b(used); + hwpf.Read1b(ver_align); + hwpf.ReadBlock(linetype, 4); + hwpf.Read1b(shade); + hwpf.Read1b(diagonal); + return hwpf.Read1b(protect); +} + +bool TxtBox::Read(HWPFile & hwpf) +{ + int ii, ncell; + + hwpf.Read2b(reserved, 2); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy || CH_TEXT_BOX != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + hwpf.Read2b(&style.cap_len, 1); + hwpf.Read2b(&dummy1, 1); + unsigned short next; + hwpf.Read2b(&next, 1); + hwpf.Read2b(&dummy2, 1); + + style.boxnum = fboxnum++; + zorder = zindex++; + hwpf.Read1b(style.anchor_type); + hwpf.Read1b(style.txtflow); + hwpf.Read2b(&style.xpos, 1); + hwpf.Read2b(&style.ypos, 1); + hwpf.Read2b(&option, 1); + hwpf.Read2b(&ctrl_ch, 1); + hwpf.Read2b(style.margin, 12); + hwpf.Read2b(&box_xs, 1); + hwpf.Read2b(&box_ys, 1); + hwpf.Read2b(&cap_xs, 1); + hwpf.Read2b(&cap_ys, 1); + hwpf.Read2b(&style.cap_len, 1); + hwpf.Read2b(&xs, 1); + hwpf.Read2b(&ys, 1); + hwpf.Read2b(&cap_margin, 1); + hwpf.Read1b(xpos_type); + hwpf.Read1b(ypos_type); + hwpf.Read1b(smart_linesp); + hwpf.Read1b(reserved1); + hwpf.Read2b(&pgx, 1); + hwpf.Read2b(&pgy, 1); + hwpf.Read2b(&pgno, 1); + if( ( pgno +1 ) != hwpf.getCurrentPage() ) + pgno = sal::static_int_cast<short>(hwpf.getCurrentPage() -1) ; + + hwpf.Read2b(&showpg, 1); + hwpf.Read2b(&cap_pos, 1); + hwpf.Read2b(&num, 1); + hwpf.Read2b(&dummy3, 1); + hwpf.Read2b(&baseline, 1); + hwpf.Read2b(&type, 1); + hwpf.Read2b(&nCell, 1); + hwpf.Read2b(&protect, 1); + switch (type) + { + case 0: //table + style.boxtype = 'T'; + break; + case 1: // text-box + style.boxtype = 'X'; + break; + case 2: // equation + style.boxtype = 'E'; + break; + case 3: // button + style.boxtype = 'B'; + break; + default: // other + style.boxtype = 'O'; + break; + } + + UpdateBBox(this); + + ncell = nCell; + if (ncell <= 0) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + + if (ncell > 4096 && utl::ConfigManager::IsFuzzing()) { + // cut off at an arbitrary size to speed up fuzzing + return hwpf.SetState(HWP_InvalidFileFormat); + } + + cell.reset( ::comphelper::newArray_null<Cell>(ncell) ); + if (!cell) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + bool bSuccess = true; + for (ii = 0; ii < ncell && bSuccess; ii++) + { + bSuccess = cell[ii].Read(hwpf); + cell[ii].key = sal::static_int_cast<unsigned char>(ii); + } + if (!bSuccess) + return false; + if (ncell == 1) + style.cell = &cell[0]; + plists.resize(ncell); + for (ii = 0; ii < ncell; ii++) + hwpf.ReadParaList(plists[ii]); + // caption + hwpf.ReadParaList(caption); + + if( type == 0 ){ // if table? + std::unique_ptr<TCell*[]> pArr(new TCell*[ncell]); + std::fill(pArr.get(), pArr.get() + ncell, nullptr); + if (!pArr) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + std::unique_ptr<Table> tbl(new Table); + for( ii = 0 ; ii < ncell; ii++) + { + tbl->columns.insert(cell[ii].x); + tbl->columns.insert(cell[ii].x + cell[ii].w); + tbl->rows.insert(cell[ii].y); + tbl->rows.insert(cell[ii].y + cell[ii].h); + } + for( ii = 0 ; ii < ncell; ii++) + { + TCell *tcell = new TCell; + tcell->nColumnIndex = tbl->columns.getIndex(cell[ii].x); + tcell->nColumnSpan = tbl->columns.getIndex(cell[ii].x + cell[ii].w) - + tcell->nColumnIndex; + tcell->nRowIndex = tbl->rows.getIndex(cell[ii].y); + tcell->nRowSpan = tbl->rows.getIndex(cell[ii].y + cell[ii].h) - + tcell->nRowIndex; + tcell->pCell = &cell[ii]; + pArr[ii] = tcell; + } + + // Sort by row and column + for( ii = 0 ; ii < ncell - 1; ii++ ){ + for( int jj = ii ; jj < ncell ; jj++){ + if( pArr[ii]->nRowIndex > pArr[jj]->nRowIndex ){ + std::swap(pArr[ii], pArr[jj]); + } + } + for( int kk = ii ; kk > 0 ; kk--){ + if( ( pArr[kk]->nRowIndex == pArr[kk-1]->nRowIndex ) && + (pArr[kk]->nColumnIndex < pArr[kk-1]->nColumnIndex )){ + std::swap(pArr[kk], pArr[kk-1]); + } + } + } + for( ii = 0 ; ii < ncell ; ii++ ){ + tbl->cells.emplace_back(pArr[ii]); + } + tbl->box = this; + m_pTable = tbl.get(); + hwpf.AddTable(std::move(tbl)); + } + else + m_pTable = nullptr; + + bSuccess = !hwpf.State(); + if (bSuccess) + hwpf.AddFBoxStyle(&style); + return bSuccess; +} + +namespace +{ + class ChangeMemGuard + { + private: + HIODev* m_pOldMem; + std::unique_ptr<HMemIODev> m_xNewMem; + public: + ChangeMemGuard(unsigned char* data, size_t nLen) + : m_pOldMem(hmem) + , m_xNewMem(std::make_unique<HMemIODev>(reinterpret_cast<char*>(data), nLen)) + { + hmem = m_xNewMem.get(); + } + ~ChangeMemGuard() + { + assert(hmem == m_xNewMem.get()); + hmem = m_pOldMem; + } + }; +} + +// picture(11) +bool Picture::Read(HWPFile & hwpf) +{ + hwpf.Read2b(reserved, 2); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy || CH_PICTURE != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + + hwpf.Read4b(follow_block_size); + + //when fuzzing with a max len set, max decompress to 10 times that limit + static size_t nMaxAllowedDecompression = [](const char* pEnv) { size_t nRet = pEnv ? std::atoi(pEnv) : 0; return nRet * 10; }(std::getenv("FUZZ_MAX_INPUT_LEN")); + + hwpf.Read2b(&dummy1, 1); /* Reserved 4 bytes */ + hwpf.Read2b(&dummy2, 1); + + style.boxnum = fboxnum++; + zorder = zindex++; + hwpf.Read1b(style.anchor_type); /* Reference position */ + hwpf.Read1b(style.txtflow); /* Avoid painting. 0-2 (seat occupied, transparency, harmony) */ + hwpf.Read2b(&style.xpos, 1); /* Horizontal position: 1=left, 2=right, 3=center, and others=any */ + hwpf.Read2b(&style.ypos, 1); /* Vertical position: 1=top, 2=down, 3=middle, and others=any */ + hwpf.Read2b(&option, 1); /* Other options: Borders, reverse picture, and so on. Save as bit. */ + hwpf.Read2b(&ctrl_ch, 1); /* Always 11 */ + hwpf.Read2b(style.margin, 12); /* Margin: [0-2] [] out / in / cell, [], [0-3] left / right / top / bottom margins */ + hwpf.Read2b(&box_xs, 1); /* Box Size Width */ + hwpf.Read2b(&box_ys, 1); /* Vertical */ + hwpf.Read2b(&cap_xs, 1); /* Caption Size Width */ + hwpf.Read2b(&cap_ys, 1); /* Vertical */ + hwpf.Read2b(&style.cap_len, 1); /* Length */ + hwpf.Read2b(&xs, 1); /* The total size (box size + caption + margin) Horizontal */ + hwpf.Read2b(&ys, 1); /* Vertical */ + hwpf.Read2b(&cap_margin, 1); /* Caption margins */ + hwpf.Read1b(xpos_type); + hwpf.Read1b(ypos_type); + hwpf.Read1b(smart_linesp); /* Line Spacing protection: 0 unprotected 1 protected */ + hwpf.Read1b(reserved1); + hwpf.Read2b(&pgx, 1); /* Real Calculated box width */ + hwpf.Read2b(&pgy, 1); /* Height */ + hwpf.Read2b(&pgno, 1); /* Page number: starts from 0 */ + hwpf.Read2b(&showpg, 1); /* Show the Box */ + hwpf.Read2b(&cap_pos, 1); /* Caption positions 0-7 Menu Order. */ + hwpf.Read2b(&num, 1); /* Box number, serial number which starts from 0 */ + + hwpf.Read1b(pictype); /* Picture type */ + + unsigned short tmp16; + if (!hwpf.Read2b(tmp16)) /* the real horizontal starting point where shows the picture */ + return false; + skip[0] = tmp16; + if (!hwpf.Read2b(tmp16)) /* Vertical */ + return false; + skip[1] = tmp16; + if (!hwpf.Read2b(tmp16)) /* Zoom Ratio: 0:fixed, others are percentage for horizontal */ + return false; + scale[0] = tmp16; + if (!hwpf.Read2b(tmp16)) /* Vertical */ + return false; + scale[1] = tmp16; + + hwpf.ReadBlock(picinfo.picun.path, 256); /* Picture File Name: when type is not a Drawing. */ + picinfo.picun.path[255] = 0; // ensure null terminated + hwpf.ReadBlock(reserved3, 9); /* Brightness / Contrast / Picture Effect, etc. */ + + UpdateBBox(this); + if( pictype != PICTYPE_DRAW ) + style.cell = reserved3; + else + { + //picinfo.picun read above is unioned with + //picinfo.picdraw and so wrote to the hdo pointer + //value, which is definitely not useful to us + picinfo.picdraw.hdo = nullptr; + } + + if (follow_block_size != 0) + { + follow.clear(); + + //read potentially compressed data in blocks as it's more + //likely large values are simply broken and we'll run out + //of data before we need to realloc + for (size_t i = 0; i < follow_block_size; i+= SAL_N_ELEMENTS(hwpf.scratch)) + { + size_t nOldSize = follow.size(); + size_t nBlock = std::min(SAL_N_ELEMENTS(hwpf.scratch), follow_block_size - nOldSize); + size_t nReadBlock = hwpf.ReadBlock(hwpf.scratch, nBlock); + if (nReadBlock) + { + follow.insert(follow.end(), hwpf.scratch, hwpf.scratch + nReadBlock); + } + if (nBlock != nReadBlock) + break; + if (nMaxAllowedDecompression && follow.size() > nMaxAllowedDecompression) + break; + } + follow_block_size = follow.size(); + + if (pictype == PICTYPE_DRAW) + { + auto xGuard(std::make_unique<ChangeMemGuard>(follow.data(), follow_block_size)); + LoadDrawingObjectBlock(this, hwpf); + style.cell = picinfo.picdraw.hdo; + xGuard.reset(); + } + else if (follow_block_size >= 4) + { + if ((follow[3] << 24 | follow[2] << 16 | follow[1] << 8 | follow[0]) == 0x269) + { + ishyper = true; + } + } + } + + if( pictype != 3 ) + style.boxtype = 'G'; + else + style.boxtype = 'D'; + +// caption + hwpf.ReadParaList(caption); + + bool bSuccess = !hwpf.State(); + if (bSuccess) + hwpf.AddFBoxStyle(&style); + return bSuccess; +} + +// line(15) +Line::Line() + : FBox(CH_LINE) + , dummy(0) + , sx(0) + , sy(0) + , ex(0) + , ey(0) + , width(0) + , shade(0) + , color(0) +{ +} + +bool Line::Read(HWPFile & hwpf) +{ + hwpf.Read2b(reserved, 2); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy || CH_LINE != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + + style.boxnum = fboxnum++; + zorder = zindex++; + style.boxtype = 'L'; + hwpf.ReadBlock(&reserved2, 8); + hwpf.Read1b(style.anchor_type); + hwpf.Read1b(style.txtflow); + hwpf.Read2b(&style.xpos, 1); + hwpf.Read2b(&style.ypos, 1); + hwpf.Read2b(&option, 1); + hwpf.Read2b(&ctrl_ch, 1); + hwpf.Read2b(style.margin, 12); + hwpf.Read2b(&box_xs, 1); + hwpf.Read2b(&box_ys, 1); + hwpf.Read2b(&cap_xs, 1); + hwpf.Read2b(&cap_ys, 1); + hwpf.Read2b(&style.cap_len, 1); + hwpf.Read2b(&xs, 1); + hwpf.Read2b(&ys, 1); + lnnumber = style.boxnum; + hwpf.linenumber = 1; + hwpf.Read2b(&boundsy, 1); + hwpf.Read2b(&boundey, 1); + hwpf.Read1b(boundx); + hwpf.Read1b(draw); + + hwpf.Read2b(&pgx, 1); + hwpf.Read2b(&pgy, 1); + hwpf.Read2b(&pgno, 1); + hwpf.Read2b(&showpg, 1); + + hwpf.Read2b(&sx, 1); + hwpf.Read2b(&sy, 1); + hwpf.Read2b(&ex, 1); + hwpf.Read2b(&sy, 1); + hwpf.Read2b(&width, 1); + hwpf.Read2b(&shade, 1); + hwpf.Read2b(&color, 1); + style.xpos = width; + + bool bSuccess = !hwpf.State(); + if (bSuccess) + hwpf.AddFBoxStyle(&style); + return bSuccess; +} + +// hidden(15) +Hidden::Hidden() + : HBox(CH_HIDDEN) + , dummy(0) +{ +} + +bool Hidden::Read(HWPFile & hwpf) +{ + hwpf.Read2b(reserved, 2); + hwpf.Read2b(&dummy, 1); + if (hh != dummy || CH_HIDDEN != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + + hwpf.ReadBlock(info, 8); + hwpf.ReadParaList(plist); + + return !hwpf.State(); +} + +// header/footer(16) +HeaderFooter::HeaderFooter() + : HBox(CH_HEADER_FOOTER) + , dummy(0) + , type(0) + , where(0) + , linenumber(0) + , m_nPageNumber(0) +{ +} + +bool HeaderFooter::Read(HWPFile & hwpf) +{ + hwpf.Read2b(reserved, 2); + hwpf.Read2b(&dummy, 1); + if (hh != dummy || CH_HEADER_FOOTER != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + + hwpf.ReadBlock(info, 8); + hwpf.Read1b(type); + hwpf.Read1b(where); + lnnumber = 0; + hwpf.ReadParaList(plist, CH_HEADER_FOOTER); + linenumber = sal::static_int_cast<unsigned char>(lnnumber); + m_nPageNumber = hwpf.getCurrentPage(); + hwpf.setMaxSettedPage(); + hwpf.AddHeaderFooter(this); + + return !hwpf.State(); +} + + +// footnote(17) +Footnote::Footnote() + : HBox(CH_FOOTNOTE) + , dummy(0) + , number(0) + , type(0) + , width(0) +{ +} + +bool Footnote::Read(HWPFile & hwpf) +{ + hwpf.Read2b(reserved, 2); + hwpf.Read2b(&dummy, 1); + if (hh != dummy || CH_FOOTNOTE != dummy) { + return hwpf.SetState(HWP_InvalidFileFormat); + } + + hwpf.ReadBlock(info, 8); + hwpf.Read2b(&number, 1); + hwpf.Read2b(&type, 1); + unsigned short tmp16; + if (!hwpf.Read2b(tmp16)) + return false; + width = tmp16; + hwpf.ReadParaList(plist, CH_FOOTNOTE); + + return !hwpf.State(); +} + +// auto number(18) +AutoNum::AutoNum() + : HBox(CH_AUTO_NUM) + , type(0) + , number(0) + , dummy(0) +{ +} + +bool AutoNum::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&type, 1); + hwpf.Read2b(&number, 1); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + + +// new number(19) +NewNum::NewNum() + : HBox(CH_NEW_NUM) + , type(0) + , number(0) + , dummy(0) +{ +} + + +bool NewNum::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&type, 1); + hwpf.Read2b(&number, 1); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + +// show page number (20) +ShowPageNum::ShowPageNum() + : HBox(CH_SHOW_PAGE_NUM) + , where(0) + , m_nPageNumber(0) + , shape(0) + , dummy(0) +{ +} + +bool ShowPageNum::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&where, 1); + hwpf.Read2b(&shape, 1); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + m_nPageNumber = hwpf.getCurrentPage(); + hwpf.setMaxSettedPage(); + hwpf.AddPageNumber(this); + return !hwpf.State(); +} + +/* 홀수쪽시작/감추기 (21) */ +PageNumCtrl::PageNumCtrl() + : HBox(CH_PAGE_NUM_CTRL) + , kind(0) + , what(0) + , dummy(0) +{ +} + +bool PageNumCtrl::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&kind, 1); + hwpf.Read2b(&what, 1); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + +// mail merge(22) +MailMerge::MailMerge() + : HBox(CH_MAIL_MERGE) + , dummy(0) +{ +} + +bool MailMerge::Read(HWPFile & hwpf) +{ + hwpf.ReadBlock(field_name, 20); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + +// char composition(23) +Compose::Compose() + : HBox(CH_COMPOSE) + , dummy(0) +{ +} + +bool Compose::Read(HWPFile & hwpf) +{ + hwpf.Read2b(compose, 3); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + +// hyphen(24) +Hyphen::Hyphen() + : HBox(CH_HYPHEN) + , width(0) + , dummy(0) +{ +} + +bool Hyphen::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&width, 1); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + + +// toc mark(25) +TocMark::TocMark() + : HBox(CH_TOC_MARK) + , kind(0) + , dummy(0) +{ +} + + +bool TocMark::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&kind, 1); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + +// index mark(26) +IndexMark::IndexMark() + : HBox(CH_INDEX_MARK) + , pgno(0) + , dummy(0) +{ +} + +bool IndexMark::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&keyword1, 60); + hwpf.Read2b(&keyword2, 60); + hwpf.Read2b(&pgno, 1); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + +// outline(28) +Outline::Outline() + : HBox(CH_OUTLINE) + , kind(0) + , shape(0) + , level(0) + , dummy(0) +{ +} + +bool Outline::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&kind, 1); + hwpf.Read1b(shape); + hwpf.Read1b(level); + hwpf.Read2b(number, 7); + hwpf.Read2b(user_shape, 7); + hwpf.Read2b(deco, 14); + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + + +/* Bundle of spaces (30)*/ +KeepSpace::KeepSpace() + : HBox(CH_KEEP_SPACE) + , dummy(0) +{ +} + + +bool KeepSpace::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + + +/* Fixed-width spaces (31) */ +FixedSpace::FixedSpace() + : HBox(CH_FIXED_SPACE) + , dummy(0) +{ +} + + +bool FixedSpace::Read(HWPFile & hwpf) +{ + hwpf.Read2b(&dummy, 1); + + if (hh != dummy){ + return hwpf.SetState(HWP_InvalidFileFormat); + } + return !hwpf.State(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |