sw/source/filter/ww8/ww8par.cxx | 39 +++++--- sw/source/filter/ww8/ww8scan.cxx | 175 +++++++++++++++++++++++++++++++++++---- sw/source/filter/ww8/ww8scan.hxx | 14 +++ 3 files changed, 195 insertions(+), 33 deletions(-)
New commits: commit e10868b72c253f00b04437692a527c076b2cfbbe Author: Oliver-Rainer Wittmann <[email protected]> Date: Tue Jun 11 10:25:37 2013 +0000 WW8 import: assure that read PLCF position arrays contain valid values diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 65945c8..70dbea9 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -4444,6 +4444,11 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos) pSBase = new WW8ScannerBase(pStrm,pTableStream,pDataStream,pWwFib); + if ( !pSBase->IsValid() ) + { + return ERR_SWG_READ_ERROR; + } + static const SvxExtNumType eNumTA[16] = { SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER, @@ -4519,23 +4524,25 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos) if (pGloss) { WW8PLCF aPlc(pTableStream, pWwFib->fcPlcfglsy, pWwFib->lcbPlcfglsy, 0); - - WW8_CP nStart, nEnd; - void* pDummy; - - for (int i=0;i<pGloss->GetNoStrings();i++,aPlc++) + if ( aPlc.IsValid() ) { - SwNodeIndex aIdx( rDoc.GetNodes().GetEndOfContent()); - SwTxtFmtColl* pColl = - rDoc.GetTxtCollFromPool(RES_POOLCOLL_STANDARD, - false); - SwStartNode *pNode = - rDoc.GetNodes().MakeTextSection(aIdx, - SwNormalStartNode,pColl); - pPaM->GetPoint()->nNode = pNode->GetIndex()+1; - pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(),0); - aPlc.Get( nStart, nEnd, pDummy ); - ReadText(nStart,nEnd-nStart-1,MAN_MAINTEXT); + WW8_CP nStart, nEnd; + void* pDummy; + + for (int i=0; i<pGloss->GetNoStrings(); i++,aPlc++) + { + SwNodeIndex aIdx( rDoc.GetNodes().GetEndOfContent()); + SwTxtFmtColl* pColl = + rDoc.GetTxtCollFromPool(RES_POOLCOLL_STANDARD, + false); + SwStartNode *pNode = + rDoc.GetNodes().MakeTextSection(aIdx, + SwNormalStartNode,pColl); + pPaM->GetPoint()->nNode = pNode->GetIndex()+1; + pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(),0); + aPlc.Get( nStart, nEnd, pDummy ); + ReadText(nStart,nEnd-nStart-1,MAN_MAINTEXT); + } } } else //ordinary case diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx index 1f6a3c3..010a36d 100644 --- a/sw/source/filter/ww8/ww8scan.cxx +++ b/sw/source/filter/ww8/ww8scan.cxx @@ -933,6 +933,28 @@ const sal_uInt8* WW8SprmIter::FindSprm(sal_uInt16 nId) return 0; // SPRM _not_ found } +namespace { + bool IsPLCFPosArrayValid( + const sal_Int32* pPLCFPosArray, + const sal_Int32 nMaxIndex ) + { + bool bIsValid = true; + + WW8_CP nValue = 0; + for ( sal_Int32 i = 0; i <= nMaxIndex; ++i ) + { + if ( pPLCFPosArray[i] < nValue ) + { + bIsValid = false; + break; + } + nValue = pPLCFPosArray[i]; + } + + return bIsValid; + } +} + //----------------------------------------- // temporaerer Test //----------------------------------------- @@ -1695,9 +1717,36 @@ void WW8ScannerBase::DeletePieceTable() WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt, SvStream* pDataSt, const WW8Fib* pWwFib ) - : pWw8Fib(pWwFib), pMainFdoa(0), pHdFtFdoa(0), pMainTxbx(0), - pMainTxbxBkd(0), pHdFtTxbx(0), pHdFtTxbxBkd(0), pMagicTables(0), - pSubdocs(0), pExtendedAtrds(0), pPieceGrpprls(0) + : pWw8Fib(pWwFib) + , pChpPLCF( 0 ) + , pPapPLCF( 0 ) + , pSepPLCF( 0 ) + , pFtnPLCF( 0 ) + , pEdnPLCF( 0 ) + , pAndPLCF( 0 ) + , pFldPLCF( 0 ) + , pFldHdFtPLCF( 0 ) + , pFldTxbxPLCF( 0 ) + , pFldTxbxHdFtPLCF( 0 ) + , pFldFtnPLCF( 0 ) + , pFldEdnPLCF( 0 ) + , pFldAndPLCF( 0 ) + , pMainFdoa(0) + , pHdFtFdoa(0) + , pMainTxbx(0) + , pMainTxbxBkd(0) + , pHdFtTxbx(0) + , pHdFtTxbxBkd(0) + , pMagicTables(0) + , pSubdocs(0) + , pExtendedAtrds(0) + , pBook( 0 ) + , pPiecePLCF( 0 ) + , pPieceIter( 0 ) + , pPLCFx_PCD( 0 ) + , pPLCFx_PCDAttrs( 0 ) + , pPieceGrpprls(0) + , nPieceGrpprls( 0 ) { pPiecePLCF = OpenPieceTable( pTblSt, pWw8Fib ); // Complex if( pPiecePLCF ) @@ -1800,14 +1849,14 @@ WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt, pSubdocs = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcfwkb, pWwFib->lcbPlcfwkb, 12); } - // Extended ATRD + // Extended ATRD if (pWwFib->fcAtrdExtra && pWwFib->lcbAtrdExtra) { pExtendedAtrds = new sal_uInt8[pWwFib->lcbAtrdExtra]; - long nOldPos = pTblSt->Tell(); - pTblSt->Seek(pWwFib->fcAtrdExtra); - pTblSt->Read(pExtendedAtrds, pWwFib->lcbAtrdExtra); - pTblSt->Seek(nOldPos); + long nOldPos = pTblSt->Tell(); + pTblSt->Seek(pWwFib->fcAtrdExtra); + pTblSt->Read(pExtendedAtrds, pWwFib->lcbAtrdExtra); + pTblSt->Seek(nOldPos); } break; @@ -1834,6 +1883,32 @@ WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt, pBook = new WW8PLCFx_Book(pTblSt, *pWwFib); } +bool WW8ScannerBase::IsValid() +{ + return ( pPiecePLCF == 0 || pPiecePLCF->IsValid() ) + && pChpPLCF->HasValidPLCF() + && pPapPLCF->HasValidPLCF() + && pSepPLCF->HasValidPLCF() + && pFtnPLCF->HasValidPLCF() + && pEdnPLCF->HasValidPLCF() + && pAndPLCF->HasValidPLCF() + && pFldPLCF->HasValidPLCF() + && pFldHdFtPLCF->HasValidPLCF() + && pFldFtnPLCF->HasValidPLCF() + && pFldEdnPLCF->HasValidPLCF() + && pFldAndPLCF->HasValidPLCF() + && pFldTxbxPLCF->HasValidPLCF() + && pFldTxbxHdFtPLCF->HasValidPLCF() + && ( pMainFdoa == 0 || pMainFdoa->IsValid() ) + && ( pHdFtFdoa == 0 || pHdFtFdoa->IsValid() ) + && ( pMainTxbxBkd == 0 || pMainTxbxBkd->IsValid() ) + && ( pHdFtTxbxBkd == 0 || pHdFtTxbxBkd->IsValid() ) + && ( pMagicTables == 0 || pMagicTables->IsValid() ) + && ( pSubdocs == 0 || pSubdocs->IsValid() ) + && ( pHdFtTxbx == 0 || pHdFtTxbx->IsValid() ) + && pBook->HasValidPLCF(); +} + WW8ScannerBase::~WW8ScannerBase() { DeletePieceTable(); @@ -2151,6 +2226,11 @@ WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, long nFilePos, long nPLCF, pSt->Seek( nOldPos ); } +bool WW8PLCFspecial::IsValid() +{ + return IsPLCFPosArrayValid( pPLCF_PosArray, nIMax ); +} + // WW8PLCFspecial::SeekPos() stellt den WW8PLCFspecial auf die Stelle nPos, wobei auch noch der // Eintrag benutzt wird, der vor nPos beginnt und bis hinter nPos reicht. // geeignet fuer normale Attribute. Allerdings wird der Attributanfang nicht @@ -2245,8 +2325,17 @@ bool WW8PLCFspecial::GetData(long nInIdx, WW8_CP& rPos, void*& rpValue) const // Ctor fuer *andere* als Fkps // Bei nStartPos < 0 wird das erste Element des PLCFs genommen -WW8PLCF::WW8PLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct, - WW8_CP nStartPos ) : pPLCF_PosArray(0), nIdx(0), nStru(nStruct) +WW8PLCF::WW8PLCF( + SvStream* pSt, + WW8_FC nFilePos, + sal_Int32 nPLCF, + int nStruct, + WW8_CP nStartPos ) + : pPLCF_PosArray( 0 ) + , pPLCF_Contents( 0 ) + , nIMax( 0 ) + , nIdx( 0 ) + , nStru( nStruct ) { ASSERT( nPLCF, "WW8PLCF: nPLCF ist Null!" ); @@ -2278,6 +2367,12 @@ WW8PLCF::WW8PLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct, SeekPos( nStartPos ); } +bool WW8PLCF::IsValid() +{ + return pPLCF_PosArray == 0 + || IsPLCFPosArrayValid( pPLCF_PosArray, nIMax ); +} + void WW8PLCF::ReadPLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF ) { bool failure = false; @@ -2469,6 +2564,11 @@ WW8PLCFpcd::WW8PLCFpcd( SvStream* pSt, long nFilePos, long nPLCF, long nStruct ) pSt->Seek( nOldPos ); } +bool WW8PLCFpcd::IsValid() +{ + return IsPLCFPosArrayValid( pPLCF_PosArray, nIMax ); +} + // Bei nStartPos < 0 wird das erste Element des PLCFs genommen WW8PLCFpcd_Iter::WW8PLCFpcd_Iter( WW8PLCFpcd& rPLCFpcd, long nStartPos ) :rPLCF( rPLCFpcd ), nIdx( 0 ) @@ -2968,6 +3068,11 @@ WW8PLCFx_Fc_FKP::~WW8PLCFx_Fc_FKP() delete pPCDAttrs; } +bool WW8PLCFx_Fc_FKP::HasValidPLCF() +{ + return pPLCF == 0 || pPLCF->IsValid(); +} + sal_uLong WW8PLCFx_Fc_FKP::GetIdx() const { sal_uLong u = pPLCF->GetIdx() << 8; @@ -3431,10 +3536,16 @@ WW8PLCFx& WW8PLCFx_Cp_FKP::operator ++( int ) //----------------------------------------- //----------------------------------------- -WW8PLCFx_SEPX::WW8PLCFx_SEPX(SvStream* pSt, SvStream* pTblSt, - const WW8Fib& rFib, WW8_CP nStartCp) - : WW8PLCFx(rFib.GetFIBVersion(), true), maSprmParser(rFib.GetFIBVersion()), - pStrm(pSt), nArrMax(256), nSprmSiz(0) +WW8PLCFx_SEPX::WW8PLCFx_SEPX( + SvStream* pSt, + SvStream* pTblSt, + const WW8Fib& rFib, + WW8_CP nStartCp) + : WW8PLCFx(rFib.GetFIBVersion(), true) + , maSprmParser(rFib.GetFIBVersion()) + , pStrm(pSt) + , nArrMax(256) + , nSprmSiz(0) { pPLCF = rFib.lcbPlcfsed ? new WW8PLCF(pTblSt, rFib.fcPlcfsed, rFib.lcbPlcfsed, @@ -3450,6 +3561,11 @@ WW8PLCFx_SEPX::~WW8PLCFx_SEPX() delete[] pSprms; } +bool WW8PLCFx_SEPX::HasValidPLCF() +{ + return pPLCF == 0 || pPLCF->IsValid(); +} + sal_uLong WW8PLCFx_SEPX::GetIdx() const { return pPLCF ? pPLCF->GetIdx() : 0; @@ -3610,10 +3726,18 @@ const sal_uInt8* WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const } //----------------------------------------- -WW8PLCFx_SubDoc::WW8PLCFx_SubDoc(SvStream* pSt, ww::WordVersion eVersion, - WW8_CP nStartCp, long nFcRef, long nLenRef, long nFcTxt, long nLenTxt, +WW8PLCFx_SubDoc::WW8PLCFx_SubDoc( + SvStream* pSt, + ww::WordVersion eVersion, + WW8_CP nStartCp, + long nFcRef, + long nLenRef, + long nFcTxt, + long nLenTxt, long nStruct) - : WW8PLCFx(eVersion, true), pRef(0), pTxt(0) + : WW8PLCFx(eVersion, true) + , pRef(0) + , pTxt(0) { if( nLenRef && nLenTxt ) { @@ -3628,6 +3752,12 @@ WW8PLCFx_SubDoc::~WW8PLCFx_SubDoc() delete pTxt; } +bool WW8PLCFx_SubDoc::HasValidPLCF() +{ + return ( pRef == 0 || pRef->IsValid() ) + && ( pTxt == 0 || pTxt->IsValid() ); +} + sal_uLong WW8PLCFx_SubDoc::GetIdx() const { // Wahrscheinlich pTxt... nicht noetig @@ -3753,6 +3883,11 @@ WW8PLCFx_FLD::~WW8PLCFx_FLD() delete pPLCF; } +bool WW8PLCFx_FLD::HasValidPLCF() +{ + return pPLCF == 0 || pPLCF->IsValid(); +} + sal_uLong WW8PLCFx_FLD::GetIdx() const { return pPLCF ? pPLCF->GetIdx() : 0; @@ -4036,6 +4171,12 @@ WW8PLCFx_Book::~WW8PLCFx_Book() delete pBook[0]; } +bool WW8PLCFx_Book::HasValidPLCF() +{ + return ( pBook[0] == 0 || pBook[0]->IsValid() ) + && ( pBook[1] == 0 || pBook[1]->IsValid() ); +} + sal_uLong WW8PLCFx_Book::GetIdx() const { return nIMax ? pBook[0]->GetIdx() : 0; diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx index bdce598..2ca4977 100644 --- a/sw/source/filter/ww8/ww8scan.hxx +++ b/sw/source/filter/ww8/ww8scan.hxx @@ -218,6 +218,7 @@ public: WW8PLCFspecial( SvStream* pSt, long nFilePos, long nPLCF, long nStruct, long nStartPos = -1 ); ~WW8PLCFspecial() { delete[] pPLCF_PosArray; } + bool IsValid(); long GetIdx() const { return nIdx; } void SetIdx( long nI ) { nIdx = nI; } long GetIMax() const { return nIMax; } @@ -301,6 +302,9 @@ public: WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN ); ~WW8PLCF(){ delete[] pPLCF_PosArray; } + + bool IsValid(); + sal_Int32 GetIdx() const { return nIdx; } void SetIdx( sal_Int32 nI ) { nIdx = nI; } sal_Int32 GetIMax() const { return nIMax; } @@ -327,6 +331,7 @@ friend class WW8PLCFpcd_Iter; public: WW8PLCFpcd( SvStream* pSt, long nFilePos, long nPLCF, long nStruct ); ~WW8PLCFpcd(){ delete[] pPLCF_PosArray; } + bool IsValid(); }; /* mehrere WW8PLCFpcd_Iter koennen auf die gleiche WW8PLCFpcd zeigen !!! */ @@ -572,6 +577,7 @@ public: WW8PLCFx_Fc_FKP( SvStream* pSt, SvStream* pTblSt, SvStream* pDataSt, const WW8Fib& rFib, ePLCFT ePl, WW8_FC nStartFcL ); virtual ~WW8PLCFx_Fc_FKP(); + bool HasValidPLCF(); virtual sal_uLong GetIdx() const; virtual void SetIdx( sal_uLong nIdx ); virtual bool SeekPos(WW8_FC nFcPos); @@ -635,6 +641,7 @@ public: WW8PLCFx_SEPX( SvStream* pSt, SvStream* pTblxySt, const WW8Fib& rFib, WW8_CP nStartCp ); virtual ~WW8PLCFx_SEPX(); + bool HasValidPLCF(); virtual sal_uLong GetIdx() const; virtual void SetIdx( sal_uLong nIdx ); long GetIMax() const { return ( pPLCF ) ? pPLCF->GetIMax() : 0; } @@ -664,6 +671,7 @@ public: WW8PLCFx_SubDoc(SvStream* pSt, ww::WordVersion eVersion, WW8_CP nStartCp, long nFcRef, long nLenRef, long nFcTxt, long nLenTxt, long nStruc = 0); virtual ~WW8PLCFx_SubDoc(); + bool HasValidPLCF(); virtual sal_uLong GetIdx() const; virtual void SetIdx( sal_uLong nIdx ); virtual bool SeekPos(WW8_CP nCpPos); @@ -694,6 +702,7 @@ private: public: WW8PLCFx_FLD(SvStream* pSt, const WW8Fib& rMyFib, short nType); virtual ~WW8PLCFx_FLD(); + bool HasValidPLCF(); virtual sal_uLong GetIdx() const; virtual void SetIdx( sal_uLong nIdx ); virtual bool SeekPos(WW8_CP nCpPos); @@ -724,6 +733,7 @@ private: public: WW8PLCFx_Book(SvStream* pTblSt,const WW8Fib& rFib); virtual ~WW8PLCFx_Book(); + bool HasValidPLCF(); long GetIMax() const { return nIMax; } virtual sal_uLong GetIdx() const; virtual void SetIdx( sal_uLong nI ); @@ -951,6 +961,7 @@ private: WW8PLCFpcd_Iter* pPieceIter; // fuer FastSave ( Iterator dazu ) WW8PLCFx_PCD* pPLCFx_PCD; // dito WW8PLCFx_PCDAttrs* pPLCFx_PCDAttrs; + sal_uInt8** pPieceGrpprls; // Attribute an Piece-Table sal_uInt16 nPieceGrpprls; // Anzahl davon @@ -960,6 +971,9 @@ public: WW8ScannerBase( SvStream* pSt, SvStream* pTblSt, SvStream* pDataSt, const WW8Fib* pWwF ); ~WW8ScannerBase(); + + bool IsValid(); // all WW8PLCF... valid? + bool AreThereFootnotes() const { return pFtnPLCF->Count() > 0; }; bool AreThereEndnotes() const { return pEdnPLCF->Count() > 0; }; _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
