summaryrefslogtreecommitdiff
path: root/hwpfilter
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-02-28 12:32:07 +0000
committerAndras Timar <andras.timar@collabora.com>2017-07-12 10:53:24 +0200
commit0560a658e65089348da43340c543612aa9cae404 (patch)
tree8368890c3505c1e692feaa248a05a285adf92b74 /hwpfilter
parent4517bf30bc5102ea30b343a3ae5cdb48cf658875 (diff)
backport various ofz findings
hwp: avoid low hanging invalid input Change-Id: I06133d6db14edb9d915c38e4c120a9d0905495dd (cherry picked from commit b9483aacadf443e57f7708f8db64aeeba4666f2a) ofz#711: direct leak Change-Id: I65ec47b4290d845f1803b20b93f149d35d9a60ea (cherry picked from commit 86463ec54dcdc562121bdb57b1ac4e85b135b2df) ofz: ReadBlock has to be HWPIDLen to be useful Change-Id: Iaa349921972bb19b40bf68c6a3b0c7128cff4b8d (cherry picked from commit 425572b9d510cee805dc4160d7e81887d8f27577) ofz: oom in reading hwp data Change-Id: I1e4dc5f474b229d4d68d3fc34bc23c88767e5e50 (cherry picked from commit 76201c60a9162804b502726a0150ca925ee08719) Missing include Change-Id: I2fb82e3c5a9b26b1016cf99e943cf0cc30225495 (cherry picked from commit 64cca8d6237ef90c3b222df36de257dbb859d99e) ofz#860 clear old data before reading new data Change-Id: I3bf5c2072a328052004c4c0551c2b125cb8ab19b Reviewed-on: https://gerrit.libreoffice.org/35165 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit 65dcd1d8195069c8c8acb3a188b8e5616c51029c) treat ParaShape like CharShape (cherry picked from commit 00aeabb61d1d535684b05145bcc98a8d8a3e10ab) Change-Id: I7870fdeee6bd097c94d7ae58b67506c4ab2a6fb5 Reviewed-on: https://gerrit.libreoffice.org/39651 Reviewed-by: Michael Stahl <mstahl@redhat.com> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit 4f949e1c3f6a378eb9c04bc7107b8972815661ea)
Diffstat (limited to 'hwpfilter')
-rw-r--r--hwpfilter/source/hinfo.h5
-rw-r--r--hwpfilter/source/hpara.cxx23
-rw-r--r--hwpfilter/source/hpara.h4
-rw-r--r--hwpfilter/source/hwpfile.cxx41
-rw-r--r--hwpfilter/source/hwpfile.h4
-rw-r--r--hwpfilter/source/hwpreader.cxx2
6 files changed, 52 insertions, 27 deletions
diff --git a/hwpfilter/source/hinfo.h b/hwpfilter/source/hinfo.h
index d16da5d09013..7f1eee0657c7 100644
--- a/hwpfilter/source/hinfo.h
+++ b/hwpfilter/source/hinfo.h
@@ -23,6 +23,8 @@
#include "hwplib.h"
#include "string.h"
+#include <vector>
+
#define CHAIN_MAX_PATH 40
#define ANNOTATION_LEN 24
@@ -77,7 +79,7 @@ struct PaperBackInfo
int range; /* 0-????, 1-????????, 3-??????, 4-?????? */
char reserved3[27];
int size;
- char *data; // image data
+ std::vector<char> data; // image data
bool isset;
PaperBackInfo()
: type(0)
@@ -87,7 +89,6 @@ struct PaperBackInfo
, flag(0)
, range(0)
, size(0)
- , data(nullptr)
, isset(false)
{
memset(reserved1, 0, sizeof(reserved1));
diff --git a/hwpfilter/source/hpara.cxx b/hwpfilter/source/hpara.cxx
index cce909ead16e..a9a6fa2c147f 100644
--- a/hwpfilter/source/hpara.cxx
+++ b/hwpfilter/source/hpara.cxx
@@ -57,10 +57,10 @@ void LineInfo::Read(HWPFile & hwpf, HWPPara *pPara)
if( pex >> 15 & 0x01 )
{
- if( pex & 0x01 )
- hwpf.AddPage();
- pPara->pshape.reserved[0] = sal::static_int_cast<unsigned char>(pex & 0x01);
- pPara->pshape.reserved[1] = sal::static_int_cast<unsigned char>(pex & 0x02);
+ if (pex & 0x01)
+ hwpf.AddPage();
+ pPara->pshape->reserved[0] = sal::static_int_cast<unsigned char>(pex & 0x01);
+ pPara->pshape->reserved[1] = sal::static_int_cast<unsigned char>(pex & 0x02);
}
}
@@ -76,10 +76,11 @@ HWPPara::HWPPara()
, ctrlflag(0)
, pstyno(0)
, cshape(new CharShape)
+ , pshape(new ParaShape)
, linfo(nullptr)
{
memset(cshape.get(), 0, sizeof(CharShape));
- memset(&pshape, 0, sizeof(pshape));
+ memset(pshape.get(), 0, sizeof(ParaShape));
}
HWPPara::~HWPPara()
@@ -109,9 +110,9 @@ bool HWPPara::Read(HWPFile & hwpf, unsigned char flag)
/* Paragraph paragraphs shape */
if (nch && !reuse_shape)
{
- pshape.Read(hwpf);
- pshape.cshape = cshape.get();
- pshape.pagebreak = etcflag;
+ pshape->Read(hwpf);
+ pshape->cshape = cshape.get();
+ pshape->pagebreak = etcflag;
}
linfo = ::comphelper::newArray_null<LineInfo>(nline);
@@ -125,8 +126,8 @@ bool HWPPara::Read(HWPFile & hwpf, unsigned char flag)
}
if (nch && !reuse_shape){
- if( pshape.coldef.ncols > 1 ){
- hwpf.SetColumnDef( &pshape.coldef );
+ if( pshape->coldef.ncols > 1 ) {
+ hwpf.SetColumnDef(&(pshape->coldef));
}
}
@@ -173,7 +174,7 @@ bool HWPPara::Read(HWPFile & hwpf, unsigned char flag)
if (hhstr[ii]->hh == CH_END_PARA)
break;
if( hhstr[ii]->hh < CH_END_PARA )
- pshape.reserved[0] = 0;
+ pshape->reserved[0] = 0;
ii += hhstr[ii]->WSize();
}
return nch && !hwpf.State();
diff --git a/hwpfilter/source/hpara.h b/hwpfilter/source/hpara.h
index b598c201b569..9810853e4245 100644
--- a/hwpfilter/source/hpara.h
+++ b/hwpfilter/source/hpara.h
@@ -104,7 +104,7 @@ class DLLEXPORT HWPPara
unsigned long ctrlflag;
unsigned char pstyno;
std::shared_ptr<CharShape> cshape; /* When characters are all the same shape */
- ParaShape pshape; /* if reuse flag is 0, */
+ std::shared_ptr<ParaShape> pshape; /* if reuse flag is 0, */
LineInfo *linfo;
std::vector<std::shared_ptr<CharShape>> cshapep;
@@ -128,7 +128,7 @@ class DLLEXPORT HWPPara
/**
* Returns the style of paragraph.
*/
- ParaShape& GetParaShape(void) { return pshape;}
+ ParaShape& GetParaShape(void) { return *pshape; }
/**
* Returns next paragraph.
diff --git a/hwpfilter/source/hwpfile.cxx b/hwpfilter/source/hwpfile.cxx
index 96395da5c6da..326c428d98f7 100644
--- a/hwpfilter/source/hwpfile.cxx
+++ b/hwpfilter/source/hwpfile.cxx
@@ -19,6 +19,7 @@
#include "precompile.h"
+#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -124,7 +125,7 @@ int HWPFile::Open(HStream * stream)
char idstr[HWPIDLen];
- if (ReadBlock(idstr, HWPIDLen) <= 0
+ if (ReadBlock(idstr, HWPIDLen) < HWPIDLen
|| HWP_V30 != (version = detect_hwp_version(idstr)))
{
return SetState(HWP_UNSUPPORTED_VERSION);
@@ -261,9 +262,9 @@ bool HWPFile::ReadParaList(std::list < HWPPara* > &aplist, unsigned char flag)
spNode->reuse_shape = 0;
}
}
- spNode->pshape.pagebreak = spNode->etcflag;
- if( spNode->nch )
- AddParaShape( &spNode->pshape );
+ spNode->pshape->pagebreak = spNode->etcflag;
+ if (spNode->nch)
+ AddParaShape(spNode->pshape);
if (!aplist.empty())
aplist.back()->SetNext(spNode.get());
@@ -347,8 +348,30 @@ void HWPFile::TagsRead()
if (!Read4b(_hwpInfo.back_info.size))
return;
- _hwpInfo.back_info.data = new char[(unsigned int)_hwpInfo.back_info.size];
- ReadBlock(_hwpInfo.back_info.data, _hwpInfo.back_info.size);
+ if (_hwpInfo.back_info.size < 0)
+ {
+ _hwpInfo.back_info.size = 0;
+ return;
+ }
+
+ _hwpInfo.back_info.data.clear();
+
+ //read potentially compressed data in blocks as its more
+ //likely large values are simply broken and we'll run out
+ //of data before we need to realloc
+ for (int i = 0; i < _hwpInfo.back_info.size; i+= SAL_MAX_UINT16)
+ {
+ int nOldSize = _hwpInfo.back_info.data.size();
+ size_t nBlock = std::min<int>(SAL_MAX_UINT16, _hwpInfo.back_info.size - nOldSize);
+ _hwpInfo.back_info.data.resize(nOldSize + nBlock);
+ size_t nReadBlock = ReadBlock(_hwpInfo.back_info.data.data() + nOldSize, nBlock);
+ if (nBlock != nReadBlock)
+ {
+ _hwpInfo.back_info.data.resize(nOldSize + nReadBlock);
+ break;
+ }
+ }
+ _hwpInfo.back_info.size = _hwpInfo.back_info.data.size();
if( _hwpInfo.back_info.size > 0 )
_hwpInfo.back_info.type = 2;
@@ -450,7 +473,7 @@ ParaShape *HWPFile::getParaShape(int index)
{
if (index < 0 || static_cast<unsigned int>(index) >= pslist.size())
return nullptr;
- return pslist[index];
+ return pslist[index].get();
}
CharShape *HWPFile::getCharShape(int index)
@@ -495,7 +518,7 @@ Table *HWPFile::getTable(int index)
return tables[index];
}
-void HWPFile::AddParaShape(ParaShape * pshape)
+void HWPFile::AddParaShape(std::shared_ptr<ParaShape>& pshape)
{
int nscount = 0;
for(int j = 0 ; j < MAXTABS-1 ; j++)
@@ -516,7 +539,7 @@ void HWPFile::AddParaShape(ParaShape * pshape)
if( nscount )
pshape->tabs[MAXTABS-1].type = sal::static_int_cast<char>(nscount);
- int value = compareParaShape(pshape);
+ int value = compareParaShape(pshape.get());
if( value == 0 || nscount )
{
diff --git a/hwpfilter/source/hwpfile.h b/hwpfilter/source/hwpfile.h
index 7f3d29f80225..d58faa569a7b 100644
--- a/hwpfilter/source/hwpfile.h
+++ b/hwpfilter/source/hwpfile.h
@@ -212,7 +212,7 @@ class DLLEXPORT HWPFile
void AddPage(){ m_nCurrentPage++;}
void AddColumnInfo();
void SetColumnDef(ColumnDef *coldef);
- void AddParaShape(ParaShape *);
+ void AddParaShape(std::shared_ptr<ParaShape>&);
void AddCharShape(std::shared_ptr<CharShape>&);
void AddFBoxStyle(FBoxStyle *);
void AddDateFormat(DateCode *);
@@ -283,7 +283,7 @@ class DLLEXPORT HWPFile
std::list<EmPicture*> emblist;
std::list<HyperText*> hyperlist;
int currenthyper;
- std::vector<ParaShape*> pslist; /* 스타오피스의 구조상 필요 */
+ std::vector<std::shared_ptr<ParaShape>> pslist; /* 스타오피스의 구조상 필요 */
std::vector<std::shared_ptr<CharShape>> cslist;
std::vector<FBoxStyle*> fbslist;
std::vector<DateCode*> datecodes;
diff --git a/hwpfilter/source/hwpreader.cxx b/hwpfilter/source/hwpreader.cxx
index 27c3b514417e..4fc026a34b04 100644
--- a/hwpfilter/source/hwpreader.cxx
+++ b/hwpfilter/source/hwpreader.cxx
@@ -1738,7 +1738,7 @@ void HwpReader::makePageStyle()
if( hwpinfo.back_info.type == 2 ){
rstartEl("office:binary-data", mxList.get());
mxList->clear();
- std::shared_ptr<char> pStr(base64_encode_string(reinterpret_cast<unsigned char *>(hwpinfo.back_info.data), hwpinfo.back_info.size ), Free<char>());
+ std::shared_ptr<char> pStr(base64_encode_string(reinterpret_cast<unsigned char *>(hwpinfo.back_info.data.data()), hwpinfo.back_info.size ), Free<char>());
rchars(ascii(pStr.get()));
rendEl("office:binary-data");
}