[Libreoffice-commits] core.git: Branch 'aoo/trunk' - sw/source

Oliver-Rainer Wittmann orw at apache.org
Tue Jun 11 05:07:28 PDT 2013


 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 <orw at apache.org>
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; };
 


More information about the Libreoffice-commits mailing list