[Libreoffice-commits] .: 9 commits - sw/qa sw/source

Caolán McNamara caolan at kemper.freedesktop.org
Mon Jul 18 04:26:28 PDT 2011


 sw/qa/core/filters-test.cxx             |   10 
 sw/source/filter/inc/msfilter.hxx       |    1 
 sw/source/filter/ww8/writerwordglue.cxx |    7 
 sw/source/filter/ww8/ww8graf.cxx        |   12 -
 sw/source/filter/ww8/ww8par.cxx         |   85 +++++--
 sw/source/filter/ww8/ww8par.hxx         |   36 +++
 sw/source/filter/ww8/ww8par6.cxx        |    7 
 sw/source/filter/ww8/ww8scan.cxx        |  373 +++++++++++++++++---------------
 sw/source/filter/ww8/ww8scan.hxx        |   28 +-
 9 files changed, 342 insertions(+), 217 deletions(-)

New commits:
commit e68dcf570f7bec639927875b1f1c2b78fc2d0551
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jul 18 10:07:02 2011 +0100

    de-stupid-operator-ize plcf and keep nIdx within legal limits

diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index 7963f0e..7d01d31 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -831,7 +831,7 @@ bool SwWW8ImplReader::GetTxbxTextSttEndCp(WW8_CP& rStartCp, WW8_CP& rEndCp,
         bool bReusable = (0 != SVBT16ToShort( ((WW8_TXBXS*)pT0)->fReusable ));
         while( bReusable )
         {
-            (*pT)++;
+            pT->advance();
             if( !pT->Get( rStartCp, pT0 ) )
             {
                 OSL_ENSURE( !this, "+Wo ist der Grafik-Text (2-a) ?" );
@@ -840,7 +840,7 @@ bool SwWW8ImplReader::GetTxbxTextSttEndCp(WW8_CP& rStartCp, WW8_CP& rEndCp,
             bReusable = (0 != SVBT16ToShort( ((WW8_TXBXS*)pT0)->fReusable ));
         }
     }
-    (*pT)++;
+    pT->advance();
     if( !pT->Get( rEndCp, pT0 ) )
     {
         OSL_ENSURE( !this, "+Wo ist der Grafik-Text (3) ?" );
@@ -868,7 +868,8 @@ bool SwWW8ImplReader::GetTxbxTextSttEndCp(WW8_CP& rStartCp, WW8_CP& rEndCp,
                 return false;
             }
             // ggfs. entsprechende Anzahl Eintraege weitergehen
-            for(sal_uInt16 iSequence = 0; iSequence < nSequence; iSequence++) (*pT)++;
+            for (sal_uInt16 iSequence = 0; iSequence < nSequence; ++iSequence)
+                pT->advance();
             // dann die tatsaechlichen Start und Ende ermitteln
             if(    (!pT->Get( rStartCp, pT0 ))
                 || ( nMinStartCp > rStartCp  ) )
@@ -880,9 +881,8 @@ bool SwWW8ImplReader::GetTxbxTextSttEndCp(WW8_CP& rStartCp, WW8_CP& rEndCp,
                 rEndCp = rStartCp;  // kein Error: leerer String!
             else
             {
-                (*pT)++;
-                if(    (!pT->Get( rEndCp, pT0 ))
-                    || ( nMaxEndCp < rEndCp-1  ) )
+                pT->advance();
+                if ( (!pT->Get(rEndCp, pT0)) || (nMaxEndCp < rEndCp-1) )
                 {
                     OSL_ENSURE( !this, "+Wo ist der Grafik-Text (6) ?" );
                     return false;
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index a13edd8..f2e1911 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -1779,7 +1779,7 @@ static bool WW8SkipField(WW8PLCFspecial& rPLCF)
     if (!rPLCF.Get(nP, pData))              // Ende des PLCFspecial ?
         return false;
 
-    rPLCF++;
+    rPLCF.advance();
 
     if((((sal_uInt8*)pData)[0] & 0x1f ) != 0x13 )    // Kein Anfang ?
         return true;                            // Bei Fehler nicht abbrechen
@@ -1800,7 +1800,7 @@ static bool WW8SkipField(WW8PLCFspecial& rPLCF)
     {
 
         // Field Separator ?
-        rPLCF++;
+        rPLCF.advance();
 
         if( !rPLCF.Get( nP, pData ) )
             return false;
@@ -1813,7 +1813,7 @@ static bool WW8SkipField(WW8PLCFspecial& rPLCF)
                 return false;
         }
     }
-    rPLCF++;
+    rPLCF.advance();
 
     return true;
 }
@@ -1828,7 +1828,7 @@ static bool WW8GetFieldPara(WW8PLCFspecial& rPLCF, WW8FieldDesc& rF)
     if( !rPLCF.Get( rF.nSCode, pData ) )             // Ende des PLCFspecial ?
         goto Err;
 
-    rPLCF++;
+    rPLCF.advance();
 
     if((((sal_uInt8*)pData)[0] & 0x1f ) != 0x13 )        // Kein Anfang ?
         goto Err;
@@ -1851,8 +1851,9 @@ static bool WW8GetFieldPara(WW8PLCFspecial& rPLCF, WW8FieldDesc& rF)
             goto Err;
     }
 
-    if((((sal_uInt8*)pData)[0] & 0x1f ) == 0x14 ){       // Field Separator ?
-        rPLCF++;
+    if ((((sal_uInt8*)pData)[0] & 0x1f ) == 0x14 )       // Field Separator ?
+    {
+        rPLCF.advance();
 
         if( !rPLCF.Get( rF.nLRes, pData ) )
             goto Err;
@@ -1875,7 +1876,7 @@ static bool WW8GetFieldPara(WW8PLCFspecial& rPLCF, WW8FieldDesc& rF)
         rF.nLen = rF.nSRes - rF.nSCode + 2;         // Gesamtlaenge
     }
 
-    rPLCF++;
+    rPLCF.advance();
     if((((sal_uInt8*)pData)[0] & 0x1f ) == 0x15 )
     {
         // Field Ende ?
@@ -3804,7 +3805,7 @@ bool WW8PLCFx_FLD::EndPosIsFieldEnd()
     {
         long n = pPLCF->GetIdx();
 
-        (*pPLCF)++;
+        pPLCF->advance();
 
         void* pData;
         sal_Int32 nTest;
@@ -3842,7 +3843,7 @@ void WW8PLCFx_FLD::GetSprms(WW8PLCFxDesc* p)
 
     p->nStartPos = nP;
 
-    (*pPLCF)++;
+    pPLCF->advance();
     if (!pPLCF->Get(nP, pData))             // Ende des PLCFspecial ?
     {
         p->nStartPos = WW8_CP_MAX;            // PLCF fertig abgearbeitet
@@ -3858,7 +3859,7 @@ void WW8PLCFx_FLD::GetSprms(WW8PLCFxDesc* p)
 
 WW8PLCFx& WW8PLCFx_FLD::operator ++( int )
 {
-    (*pPLCF)++;
+    pPLCF->advance();
     return *this;
 }
 
@@ -4120,7 +4121,7 @@ WW8PLCFx& WW8PLCFx_Book::operator ++( int )
 {
     if( pBook[0] && pBook[1] && nIMax )
     {
-        (*pBook[nIsEnd])++;
+        (*pBook[nIsEnd]).advance();
 
         sal_uLong l0 = pBook[0]->Where();
         sal_uLong l1 = pBook[1]->Where();
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 33a165f..b2d7747 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -224,7 +224,7 @@ public:
         sal_uInt32 nStruct);
     ~WW8PLCFspecial() { delete[] pPLCF_PosArray; }
     long GetIdx() const { return nIdx; }
-    void SetIdx( long nI ) { nIdx = nI; }   
+    void SetIdx( long nI ) { nIdx = nI; }
     long GetIMax() const { return nIMax; }
     bool SeekPos(long nPos);            // geht ueber FC- bzw. CP-Wert
                                         // bzw. naechste groesseren Wert
@@ -242,8 +242,11 @@ public:
     sal_Int32 GetPos( long nInIdx ) const
         { return ( nInIdx >= nIMax ) ? SAL_MAX_INT32 : pPLCF_PosArray[nInIdx]; }
 
-    WW8PLCFspecial& operator ++( int ) { nIdx++; return *this; }
-    WW8PLCFspecial& operator --( int ) { nIdx--; return *this; }
+    void advance()
+    {
+        if (nIdx <= nIMax)
+            ++nIdx;
+    }
 };
 
 /** simple Iterator for SPRMs */
commit 467b1308139c73f4de47fff06d19730d2b69ad43
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jul 18 01:12:43 2011 +0100

    merge PAP and CHP length and offset clipping

diff --git a/sw/qa/core/filters-test.cxx b/sw/qa/core/filters-test.cxx
index 9ace6d6..71e5d74 100644
--- a/sw/qa/core/filters-test.cxx
+++ b/sw/qa/core/filters-test.cxx
@@ -97,6 +97,7 @@ private:
     uno::Reference<lang::XMultiComponentFactory> m_xFactory;
     uno::Reference<uno::XInterface> m_xWriterComponent;
     ::rtl::OUString m_aSrcRoot;
+    int m_nLoadedDocs;
 };
 
 bool FiltersTest::load(const rtl::OUString &rFilter, const rtl::OUString &rURL,
@@ -110,7 +111,11 @@ bool FiltersTest::load(const rtl::OUString &rFilter, const rtl::OUString &rURL,
     SwDocShellRef xDocShRef = new SwDocShell;
     SfxMedium aSrcMed(rURL, STREAM_STD_READ, true);
     aSrcMed.SetFilter(&aFilter);
-    return xDocShRef->DoLoad(&aSrcMed);
+    bool bRet = xDocShRef->DoLoad(&aSrcMed);
+
+    ++m_nLoadedDocs;
+
+    return bRet;
 }
 
 void FiltersTest::recursiveScan(const rtl::OUString &rFilter, const rtl::OUString &rURL, const rtl::OUString &rUserData, int nExpected)
@@ -177,10 +182,13 @@ void FiltersTest::testCVEs()
     recursiveScan(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MS Word 97")), m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/clone/writer/sw/qa/core/data/ww8/fail")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CWW8")), false);
 
     recursiveScan(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MS Word 97")), m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/clone/writer/sw/qa/core/data/ww8/indeterminate")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CWW8")), indeterminate);
+
+    printf("Writer: tested %d files\n", m_nLoadedDocs);
 }
 
 FiltersTest::FiltersTest()
     : m_aSrcRoot(RTL_CONSTASCII_USTRINGPARAM("file://"))
+    , m_nLoadedDocs(0)
 {
     m_xContext = cppu::defaultBootstrap_InitialComponentContext();
     m_xFactory = m_xContext->getServiceManager();
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index a5acf1a..a13edd8 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -2473,6 +2473,25 @@ bool IsExpandableSprm(sal_uInt16 nSpId)
     return 0x646B == nSpId;
 }
 
+void WW8PLCFx_Fc_FKP::WW8Fkp::FillEntry(WW8PLCFx_Fc_FKP::WW8Fkp::Entry &rEntry,
+    sal_Size nDataOffset, sal_uInt16 nLen)
+{
+    bool bValidPos = (nDataOffset < sizeof(maRawData));
+
+    OSL_ENSURE(bValidPos, "sprm sequence offset is out of range, ignoring");
+
+    if (!bValidPos)
+    {
+        rEntry.mnLen = 0;
+        return;
+    }
+
+    sal_uInt16 nAvailableData = sizeof(maRawData)-nDataOffset;
+    OSL_ENSURE(nLen <= nAvailableData, "srpm sequence len is out of range, clipping");
+    rEntry.mnLen = std::min(nLen, nAvailableData);
+    rEntry.mpData = maRawData + nDataOffset;
+}
+
 WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion, SvStream* pSt,
     SvStream* pDataSt, long _nFilePos, long nItemSiz, ePLCFT ePl,
     WW8_FC nStartFc)
@@ -2517,8 +2536,13 @@ WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion, SvStream* pSt,
             switch (ePLCF)
             {
                 case CHP:
-                    aEntry.mnLen  = maRawData[nOfs];
-                    aEntry.mpData = maRawData + nOfs + 1;
+                {
+                    aEntry.mnLen = maRawData[nOfs];
+
+                    //len byte
+                    sal_Size nDataOffset = nOfs + 1;
+
+                    FillEntry(aEntry, nDataOffset, aEntry.mnLen);
 
                     if (aEntry.mnLen && eVersion == ww::eWW2)
                     {
@@ -2532,8 +2556,8 @@ WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion, SvStream* pSt,
                             aEntry.mbMustDelete = true;
                         }
                     }
-
                     break;
+                }
                 case PAP:
                     {
                         sal_uInt8 nDelta = 0;
@@ -2576,18 +2600,8 @@ WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion, SvStream* pSt,
                                 {
                                     //additional istd
                                     nDataOffset += sizeof(aEntry.mnIStd);
-                                    OSL_ENSURE(nDataOffset < sizeof(maRawData),
-                                        "sprm offset is out of range, ignoring");
-                                    if (nDataOffset < sizeof(maRawData))
-                                    {
-                                        aEntry.mpData = maRawData + nDataOffset;
-                                        sal_uInt16 nAvailableData = sizeof(maRawData)-nDataOffset;
-                                        OSL_ENSURE(aEntry.mnLen <= nAvailableData,
-                                            "srpm len is out of range, clipping");
-                                        aEntry.mnLen = std::min(aEntry.mnLen, nAvailableData);
-                                    }
-                                    else
-                                        aEntry.mnLen = 0;
+
+                                    FillEntry(aEntry, nDataOffset, aEntry.mnLen);
                                 }
                             }
                             else
@@ -2644,8 +2658,11 @@ WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion, SvStream* pSt,
             sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen );
 
             WW8SprmIter aIter(pSprms, nLen, maSprmParser);
-            while(aIter.GetSprms())
+            while (aIter.GetSprms())
+            {
+                fprintf(stderr, "id is %x\n", aIter.GetAktId());
                 aIter.advance();
+            }
         }
 #endif
     }
@@ -4355,7 +4372,7 @@ void WW8PLCFMan::GetNewNoSprms( WW8PLCFxDesc& rDesc )
 
 sal_uInt16 WW8PLCFMan::GetId(const WW8PLCFxDesc* p) const
 {
-    sal_uInt16 nId;
+    sal_uInt16 nId = 0;        // Id = 0 for empty attributes
 
     if (p == pFld)
         nId = eFLD;
@@ -4365,10 +4382,8 @@ sal_uInt16 WW8PLCFMan::GetId(const WW8PLCFxDesc* p) const
         nId = eEDN;
     else if (p == pAnd)
         nId = eAND;
-    else if (p->nSprmsLen > 0)
+    else if (p->nSprmsLen >= maSprmParser.MinSprmLen())
         nId = maSprmParser.GetSprmId(p->pMemPos);
-    else
-        nId = 0;        // Id = 0 for empty attributes
 
     return nId;
 }
@@ -4666,7 +4681,7 @@ void WW8PLCFMan::GetSprmStart( short nIdx, WW8PLCFManResult* pRes ) const
     pRes->nCp2OrIdx = p->nCp2OrIdx;
     if ((p == pFtn) || (p == pEdn) || (p == pAnd))
         pRes->nMemLen = p->nSprmsLen;
-    else if (p->nSprmsLen)  //Normal
+    else if (p->nSprmsLen >= maSprmParser.MinSprmLen()) //Normal
     {
         // Length of actual sprm
         pRes->nMemLen = maSprmParser.GetSprmSize(pRes->nSprmId, pRes->pMemPos);
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 2f83cba..33a165f 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -507,6 +507,9 @@ public:
         sal_uInt8 mnIMax;         // Anzahl der Eintraege
         
         wwSprmParser maSprmParser;
+
+        //Fill in an Entry with sanity testing
+        void FillEntry(Entry &rEntry, sal_Size nDataOffset, sal_uInt16 nLen);
     public:
         WW8Fkp (ww::WordVersion eVersion, SvStream* pFKPStrm, 
             SvStream* pDataStrm, long _nFilePos, long nItemSiz, ePLCFT ePl, 
commit 80305b54419752026ec3bc7f041c8f9d6c147b08
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sun Jul 17 21:25:18 2011 +0100

    check if strlen is even possible

diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index e34973a..99e2fbf 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -2635,28 +2635,42 @@ sal_Unicode SwWW8ImplReader::TranslateToHindiNumbers(sal_Unicode nChar)
 // Returnwert: true for no Sonderzeichen
 bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, long nEnd, long nCpOfs)
 {
-    // Unicode-Flag neu setzen und notfalls File-Pos korrigieren
-    // merke: Seek kostet nicht viel, da inline geprueft wird,
-    //        ob die korrekte FilePos nicht schon erreicht ist.
-    xub_StrLen nLen;
-    if (nEnd - rPos <= (STRING_MAXLEN-1))
-        nLen = writer_cast<xub_StrLen>(nEnd - rPos);
-    else
-        nLen = STRING_MAXLEN-1;
-    OSL_ENSURE(nLen, "String is 0");
-    if (!nLen)
+    sal_Size nRequestedStrLen = nEnd - rPos;
+
+    OSL_ENSURE(nRequestedStrLen, "String is 0");
+    if (!nRequestedStrLen)
         return true;
 
     sal_Size nRequestedPos = pSBase->WW8Cp2Fc(nCpOfs+rPos, &bIsUnicode);
-    sal_Size nSeekedPos = pStrm->Seek(nRequestedPos);
-    OSL_ENSURE(nRequestedPos == nSeekedPos, "Document claimed to have more text than available");
-    if (nRequestedPos != nSeekedPos)
+    bool bValidPos = checkSeek(*pStrm, nRequestedPos);
+    OSL_ENSURE(bValidPos, "Document claimed to have more text than available");
+    if (!bValidPos)
     {
         //Swallow missing range, e.g. #i95550#
-        rPos+=nLen;
+        rPos+=nRequestedStrLen;
         return true;
     }
 
+    sal_Size nAvailableStrLen = pStrm->remainingSize() / (bIsUnicode ? 2 : 1);
+    OSL_ENSURE(nAvailableStrLen, "Document claimed to have more text than available");
+    if (!nAvailableStrLen)
+    {
+        //Swallow missing range, e.g. #i95550#
+        rPos+=nRequestedStrLen;
+        return true;
+    }
+
+    sal_Size nValidStrLen = std::min(nRequestedStrLen, nAvailableStrLen);
+
+    // Unicode-Flag neu setzen und notfalls File-Pos korrigieren
+    // merke: Seek kostet nicht viel, da inline geprueft wird,
+    //        ob die korrekte FilePos nicht schon erreicht ist.
+    xub_StrLen nStrLen;
+    if (nValidStrLen <= (STRING_MAXLEN-1))
+        nStrLen = writer_cast<xub_StrLen>(nValidStrLen);
+    else
+        nStrLen = STRING_MAXLEN-1;
+
     const CharSet eSrcCharSet = bVer67 ? GetCurrentCharSet() :
         RTL_TEXTENCODING_MS_1252;
     const CharSet eSrcCJKCharSet = bVer67 ? GetCurrentCJKCharSet() :
@@ -2665,7 +2679,7 @@ bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, long nEnd, long nCpOfs)
     // (re)alloc UniString data
     String sPlainCharsBuf;
 
-    sal_Unicode* pBuffer = sPlainCharsBuf.AllocBuffer( nLen );
+    sal_Unicode* pBuffer = sPlainCharsBuf.AllocBuffer(nStrLen);
     sal_Unicode* pWork = pBuffer;
 
     sal_Char* p8Bits = NULL;
@@ -2675,7 +2689,7 @@ bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, long nEnd, long nCpOfs)
         hConverter = rtl_createTextToUnicodeConverter(eSrcCharSet);
 
     if (!bIsUnicode)
-        p8Bits = new sal_Char[nLen];
+        p8Bits = new sal_Char[nStrLen];
 
     // read the stream data
     sal_uInt8   nBCode = 0;
@@ -2687,7 +2701,7 @@ bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, long nEnd, long nCpOfs)
     if (pItem != NULL)
         nCTLLang = dynamic_cast<const SvxLanguageItem *>(pItem)->GetLanguage();
 
-    for( nL2 = 0; nL2 < nLen; ++nL2, ++pWork )
+    for( nL2 = 0; nL2 < nStrLen; ++nL2, ++pWork )
     {
         if (bIsUnicode)
             *pStrm >> nUCode;   // unicode  --> read 2 bytes
@@ -2742,9 +2756,9 @@ bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, long nEnd, long nCpOfs)
         xub_StrLen nEndUsed = nL2;
 
         if (!bIsUnicode)
-            nEndUsed = Custom8BitToUnicode(hConverter, p8Bits, nL2, pBuffer, nLen);
+            nEndUsed = Custom8BitToUnicode(hConverter, p8Bits, nL2, pBuffer, nStrLen);
 
-        for( xub_StrLen nI = 0; nI < nLen; ++nI, ++pBuffer )
+        for( xub_StrLen nI = 0; nI < nStrLen; ++nI, ++pBuffer )
             if (m_bRegardHindiDigits && bBidi && LangUsesHindiNumbers(nCTLLang))
                 *pBuffer = TranslateToHindiNumbers(*pBuffer);
 
@@ -2759,7 +2773,7 @@ bool SwWW8ImplReader::ReadPlainChars(WW8_CP& rPos, long nEnd, long nCpOfs)
     if (hConverter)
         rtl_destroyTextToUnicodeConverter(hConverter);
     delete [] p8Bits;
-    return nL2 >= nLen;
+    return nL2 >= nStrLen;
 }
 
 #define MSASCII SAL_MAX_INT16
@@ -3029,10 +3043,12 @@ bool SwWW8ImplReader::ReadChar(long nPosCp, long nCpOfs)
     // Unicode-Flag neu setzen und notfalls File-Pos korrigieren
     // merke: Seek kostet nicht viel, da inline geprueft wird,
     //        ob die korrekte FilePos nicht schon erreicht ist.
-    pStrm->Seek( pSBase->WW8Cp2Fc(nCpOfs+nPosCp, &bIsUnicode) );
+    sal_Size nRequestedPos = pSBase->WW8Cp2Fc(nCpOfs+nPosCp, &bIsUnicode);
+    if (!checkSeek(*pStrm, nRequestedPos))
+        return false;
 
-    sal_uInt8   nBCode;
-    sal_uInt16 nWCharVal;
+    sal_uInt8 nBCode(0);
+    sal_uInt16 nWCharVal(0);
     if( bIsUnicode )
         *pStrm >> nWCharVal;    // unicode  --> read 2 bytes
     else
commit 763801f3af271d6c250f1c33785a0082f303da5e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sun Jul 17 00:19:00 2011 +0100

    check seeks, check available size, pointers to ref

diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 750182e..e34973a 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -4554,7 +4554,7 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos)
     // loop for each glossary entry and add dummy section node
     if (pGloss)
     {
-        WW8PLCF aPlc(pTableStream, pWwFib->fcPlcfglsy, pWwFib->lcbPlcfglsy, 0);
+        WW8PLCF aPlc(*pTableStream, pWwFib->fcPlcfglsy, pWwFib->lcbPlcfglsy, 0);
 
         WW8_CP nStart, nEnd;
         void* pDummy;
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index d5f31a8..a5acf1a 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -2153,14 +2153,14 @@ 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& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
+    WW8_CP nStartPos) : pPLCF_PosArray(0), nIdx(0), nStru(nStruct)
 {
     OSL_ENSURE( nPLCF, "WW8PLCF: nPLCF ist Null!" );
 
     nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
 
-    ReadPLCF( pSt, nFilePos, nPLCF );
+    ReadPLCF(rSt, nFilePos, nPLCF);
 
     if( nStartPos >= 0 )
         SeekPos( nStartPos );
@@ -2171,32 +2171,33 @@ WW8PLCF::WW8PLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
 // != 0, dann wird ein unvollstaendiger PLCF vervollstaendigt.  Das ist bei
 // WW6 bei Resourcenmangel und bei WordPad (W95) immer noetig.  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, sal_Int32 nPN, sal_Int32 ncpN ) : pPLCF_PosArray(0), nIdx(0),
+WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
+    WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN): pPLCF_PosArray(0), nIdx(0),
     nStru(nStruct)
 {
     nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
 
     if( nIMax >= ncpN )
-        ReadPLCF( pSt, nFilePos, nPLCF );
+        ReadPLCF(rSt, nFilePos, nPLCF);
     else
-        GeneratePLCF( pSt, nPN, ncpN );
+        GeneratePLCF(rSt, nPN, ncpN);
 
     if( nStartPos >= 0 )
         SeekPos( nStartPos );
 }
 
-void WW8PLCF::ReadPLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF )
+void WW8PLCF::ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF)
 {
-    sal_Size nOldPos = pSt->Tell();
+    sal_Size nOldPos = rSt.Tell();
+    sal_Size nRemainingSize = rSt.remainingSize();
 
-    bool bValid = checkSeek(*pSt, nFilePos);
+    bool bValid = checkSeek(rSt, nFilePos) && (nRemainingSize >= nPLCF);
 
     if (bValid)
     {
         // Pointer auf Pos-Array
         pPLCF_PosArray = new WW8_CP[ ( nPLCF + 3 ) / 4 ];
-        bValid = checkRead(*pSt, pPLCF_PosArray, nPLCF);
+        bValid = checkRead(rSt, pPLCF_PosArray, nPLCF);
     }
 
     if (bValid)
@@ -2215,7 +2216,7 @@ void WW8PLCF::ReadPLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF )
     if (!bValid)
         MakeFailedPLCF();
 
-    pSt->Seek(nOldPos);
+    rSt.Seek(nOldPos);
 }
 
 void WW8PLCF::MakeFailedPLCF()
@@ -2227,7 +2228,7 @@ void WW8PLCF::MakeFailedPLCF()
     pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
 }
 
-void WW8PLCF::GeneratePLCF( SvStream* pSt, sal_Int32 nPN, sal_Int32 ncpN )
+void WW8PLCF::GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN)
 {
     OSL_ENSURE( nIMax < ncpN, "Pcl.Fkp: Warum ist PLCF zu gross ?" );
 
@@ -2243,32 +2244,43 @@ void WW8PLCF::GeneratePLCF( SvStream* pSt, sal_Int32 nPN, sal_Int32 ncpN )
         size_t nElems = ( nSiz + 3 ) / 4;
         pPLCF_PosArray = new sal_Int32[ nElems ]; // Pointer auf Pos-Array
 
-        for (sal_Int32 i = 0; i < ncpN && !pSt->GetError(); ++i)
+        for (sal_Int32 i = 0; i < ncpN && !failure; ++i)
         {
+            failure = true;
             // Baue FC-Eintraege
-            pSt->Seek( ( nPN + i ) << 9 );  // erster FC-Eintrag jedes Fkp
-            WW8_CP nFc;
-            *pSt >> nFc;
+            // erster FC-Eintrag jedes Fkp
+            if (checkSeek(rSt, ( nPN + i ) << 9 ))
+                continue;
+            WW8_CP nFc(0);
+            rSt >> nFc;
             pPLCF_PosArray[i] = nFc;
+            failure = rSt.GetError();
         }
-
-        failure = pSt->GetError();
     }
 
     if (!failure)
     {
-        sal_Size nLastFkpPos = ( ( nPN + nIMax - 1 ) << 9 );
-        pSt->Seek( nLastFkpPos + 511 );     // Anz. Fkp-Eintraege des letzten Fkp
+        do
+        {
+            failure = true;
+
+            sal_Size nLastFkpPos = ( ( nPN + nIMax - 1 ) << 9 );
+            // Anz. Fkp-Eintraege des letzten Fkp
+            if (!checkSeek(rSt, nLastFkpPos + 511))
+                break;
 
-        sal_uInt8 nb;
-        *pSt >> nb;
-        pSt->Seek( nLastFkpPos + nb * 4 );  // letzer FC-Eintrag des letzten Fkp
+            sal_uInt8 nb(0);
+            rSt >> nb;
+            // letzer FC-Eintrag des letzten Fkp
+            if (!checkSeek(rSt, nLastFkpPos + nb * 4))
+                break;
 
-        WW8_CP nFc;
-        *pSt >> nFc;
-        pPLCF_PosArray[nIMax] = nFc;        // Ende des letzten Fkp
+            WW8_CP nFc(0);
+            rSt >> nFc;
+            pPLCF_PosArray[nIMax] = nFc;        // Ende des letzten Fkp
 
-        failure = pSt->GetError();
+            failure = rSt.GetError();
+        } while(0);
     }
 
     if (!failure)
@@ -2358,9 +2370,11 @@ WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
     const sal_uInt32 nValidMin=4;
 
     sal_Size nOldPos = pSt->Tell();
+    sal_Size nRemainingSize = pSt->remainingSize();
 
-    bool bValid = (nPLCF >= nValidMin) && checkSeek(*pSt, nFilePos);
-    nPLCF = bValid ? std::max(nPLCF, nValidMin) : nValidMin;
+    bool bValid = checkSeek(*pSt, nFilePos) && (nRemainingSize >= nValidMin) &&
+        (nPLCF >= nValidMin);
+    nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
 
     pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];    // Pointer auf Pos-Array
     pPLCF_PosArray[0] = 0;
@@ -2923,12 +2937,12 @@ WW8PLCFx_Fc_FKP::WW8PLCFx_Fc_FKP(SvStream* pSt, SvStream* pTblSt,
     long nLenStruct = (8 > rFib.nVersion) ? 2 : 4;
     if (ePl == CHP)
     {
-        pPLCF = new WW8PLCF(pTblSt, rFib.fcPlcfbteChpx, rFib.lcbPlcfbteChpx,
+        pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbteChpx, rFib.lcbPlcfbteChpx,
             nLenStruct, GetStartFc(), rFib.pnChpFirst, rFib.cpnBteChp);
     }
     else
     {
-        pPLCF = new WW8PLCF(pTblSt, rFib.fcPlcfbtePapx, rFib.lcbPlcfbtePapx,
+        pPLCF = new WW8PLCF(*pTblSt, rFib.fcPlcfbtePapx, rFib.lcbPlcfbtePapx,
             nLenStruct, GetStartFc(), rFib.pnPapFirst, rFib.cpnBtePap);
     }
 }
@@ -3416,7 +3430,7 @@ WW8PLCFx_SEPX::WW8PLCFx_SEPX(SvStream* pSt, SvStream* pTblSt,
     pStrm(pSt), nArrMax(256), nSprmSiz(0)
 {
     pPLCF =   rFib.lcbPlcfsed
-            ? new WW8PLCF(pTblSt, rFib.fcPlcfsed, rFib.lcbPlcfsed, 
+            ? new WW8PLCF(*pTblSt, rFib.fcPlcfsed, rFib.lcbPlcfsed,
               GetFIBVersion() <= ww::eWW2 ? 6 : 12, nStartCp)
             : 0;
 
@@ -3596,8 +3610,8 @@ WW8PLCFx_SubDoc::WW8PLCFx_SubDoc(SvStream* pSt, ww::WordVersion eVersion,
 {
     if( nLenRef && nLenTxt )
     {
-        pRef = new WW8PLCF( pSt, nFcRef, nLenRef, nStruct, nStartCp );
-        pTxt = new WW8PLCF( pSt, nFcTxt, nLenTxt, 0, nStartCp );
+        pRef = new WW8PLCF(*pSt, nFcRef, nLenRef, nStruct, nStartCp);
+        pTxt = new WW8PLCF(*pSt, nFcTxt, nLenTxt, 0, nStartCp);
     }
 }
 
@@ -6523,7 +6537,7 @@ const WW8_FFN* WW8Fonts::GetFont( sal_uInt16 nNum ) const
 // -> dann liefert GetTextPos() vielleicht auch ein richtiges Ergebnis
 
 WW8PLCF_HdFt::WW8PLCF_HdFt( SvStream* pSt, WW8Fib& rFib, WW8Dop& rDop )
-    : aPLCF( pSt, rFib.fcPlcfhdd , rFib.lcbPlcfhdd , 0 )
+    : aPLCF(*pSt, rFib.fcPlcfhdd , rFib.lcbPlcfhdd , 0)
 {
     nIdxOffset = 0;
 
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 039b5e3..2f83cba 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -286,24 +286,24 @@ private:
     sal_Int32 nIdx;
     int nStru;
 
-    void ReadPLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF );
+    void ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF);
 
     /*
         Falls im Dok ein PLC fehlt und die FKPs solo dastehen,
         machen wir uns hiermit einen PLC:
     */
-    void GeneratePLCF( SvStream* pSt, sal_Int32 nPN, sal_Int32 ncpN );
+    void GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN);
 
     void MakeFailedPLCF();
 public:
-    WW8PLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct, 
-        WW8_CP nStartPos = -1 );
+    WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
+        WW8_CP nStartPos = -1);
 
     /*
         folgender Ctor generiert ggfs. einen PLC aus nPN und ncpN
     */
-    WW8PLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct, 
-        WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN );
+    WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
+        WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN);
 
     ~WW8PLCF(){ delete[] pPLCF_PosArray; }
     sal_Int32 GetIdx() const { return nIdx; }
commit 1570e35b88db93ee5a33809fa4e80054a3f417bf
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Jul 16 23:33:03 2011 +0100

    clip silly allocs

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 09608bd..d5f31a8 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -2031,9 +2031,11 @@ WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos,
     const sal_uInt32 nValidMin=4;
 
     sal_Size nOldPos = pSt->Tell();
+    sal_Size nRemainingSize = pSt->remainingSize();
 
-    bool bValid = (nPLCF >= nValidMin) && checkSeek(*pSt, nFilePos);
-    nPLCF = bValid ? std::max(nPLCF, nValidMin) : nValidMin;
+    bool bValid = checkSeek(*pSt, nFilePos) && (nRemainingSize >= nValidMin) &&
+        (nPLCF >= nValidMin);
+    nPLCF = bValid ? std::min(nRemainingSize, static_cast<sal_Size>(nPLCF)) : nValidMin;
 
     // Pointer auf Pos- u. Struct-Array
     pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];
commit b7aae6df48abf695bbf9068fc6639f9f78aa3ff2
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Jul 15 23:52:01 2011 +0100

    if the offset doesn't exist, don't bother

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 60e1bcd..09608bd 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -3853,122 +3853,126 @@ void WW8ReadSTTBF(bool bVer8, SvStream& rStrm, sal_uInt32 nStart, sal_Int32 nLen
     sal_uInt16 nExtraLen, rtl_TextEncoding eCS, std::vector<String> &rArray,
     std::vector<ww::bytes>* pExtraArray, ::std::vector<String>* pValueArray)
 {
-    if(nLen==0)     // Handle Empty STTBF
+    if (nLen==0)     // Handle Empty STTBF
         return;
 
-    sal_uLong nOldPos = rStrm.Tell();
-    rStrm.Seek( nStart );
-
-    sal_uInt16 nLen2;
-    rStrm >> nLen2; // bVer67: total length of structure
-                    // bVer8 : count of strings
-
-    if( bVer8 )
+    sal_Size nOldPos = rStrm.Tell();
+    if (checkSeek(rStrm, nStart))
     {
-        sal_uInt16 nStrings;
-        bool bUnicode = (0xFFFF == nLen2);
-        if( bUnicode )
-            rStrm >> nStrings;
-        else
-            nStrings = nLen2;
-
-        rStrm >> nExtraLen;
+        sal_uInt16 nLen2(0);
+        rStrm >> nLen2; // bVer67: total length of structure
+                        // bVer8 : count of strings
 
-        for( sal_uInt16 i=0; i < nStrings; i++ )
+        if( bVer8 )
         {
-            if( bUnicode )
-                rArray.push_back(WW8Read_xstz(rStrm, 0, false));
+            sal_uInt16 nStrings(0);
+            bool bUnicode = (0xFFFF == nLen2);
+            if (bUnicode)
+                rStrm >> nStrings;
             else
-            {
-                sal_uInt8 nBChar;
-                rStrm >> nBChar;
-                ByteString aTmp;
-                SafeReadString(aTmp,nBChar,rStrm);
-                rArray.push_back(String(aTmp, eCS));
-            }
+                nStrings = nLen2;
+
+            rStrm >> nExtraLen;
 
-            // Skip the extra data
-            if( nExtraLen )
+            for (sal_uInt16 i=0; i < nStrings; ++i)
             {
-                if (pExtraArray)
+                if (bUnicode)
+                    rArray.push_back(WW8Read_xstz(rStrm, 0, false));
+                else
+                {
+                    sal_uInt8 nBChar(0);
+                    rStrm >> nBChar;
+                    ByteString aTmp;
+                    SafeReadString(aTmp,nBChar,rStrm);
+                    rArray.push_back(String(aTmp, eCS));
+                }
+
+                // Skip the extra data
+                if (nExtraLen)
                 {
-                    ww::bytes extraData;
-                    sal_uInt8 iTmp;
-                    for(int j = 0; j < nExtraLen; ++j)
+                    if (pExtraArray)
                     {
-                        rStrm >> iTmp;
-                        extraData.push_back(iTmp);
+                        ww::bytes extraData;
+                        for (sal_uInt16 j = 0; j < nExtraLen; ++j)
+                        {
+                            sal_uInt8 iTmp(0);
+                            rStrm >> iTmp;
+                            extraData.push_back(iTmp);
+                        }
+                        pExtraArray->push_back(extraData);
                     }
-                    pExtraArray->push_back(extraData);
+                    else
+                        rStrm.SeekRel( nExtraLen );
                 }
-                else
-                    rStrm.SeekRel( nExtraLen );
             }
-        }
-        // read the value of the document variables, if requested.
-        if (pValueArray)
-        {
-                for( sal_uInt16 i=0; i < nStrings; i++ )
+            // read the value of the document variables, if requested.
+            if (pValueArray)
+            {
+                for (sal_uInt16 i=0; i < nStrings; ++i)
                 {
-                        if( bUnicode )
-                                pValueArray->push_back(WW8Read_xstz(rStrm, 0, false));
-                        else
-                        {
-                                sal_uInt8 nBChar;
-                                rStrm >> nBChar;
-                                ByteString aTmp;
-                                SafeReadString(aTmp,nBChar,rStrm);
-                                pValueArray->push_back(String(aTmp, eCS));
-                        }
+                    if( bUnicode )
+                        pValueArray->push_back(WW8Read_xstz(rStrm, 0, false));
+                    else
+                    {
+                        sal_uInt8 nBChar(0);
+                        rStrm >> nBChar;
+                        ByteString aTmp;
+                        SafeReadString(aTmp,nBChar,rStrm);
+                        pValueArray->push_back(String(aTmp, eCS));
+                    }
                 }
+            }
         }
-    }
-    else
-    {
-        sal_uInt8 nBChar;
-        if( nLen2 != nLen )
-        {
-            OSL_ENSURE( nLen2 == nLen, "Fib length and read length are different" );
-            if (nLen > USHRT_MAX)
-                nLen = USHRT_MAX;
-            else if (nLen < 2 )
-                nLen = 2;
-            nLen2 = static_cast<sal_uInt16>(nLen);
-        }
-        sal_uLong nRead = 0;
-        for( nLen2 -= 2; nRead < nLen2;  )
+        else
         {
-            rStrm >> nBChar; ++nRead;
-            if (nBChar)
+            if( nLen2 != nLen )
             {
-                ByteString aTmp;
-                nRead += SafeReadString(aTmp,nBChar,rStrm);
-                rArray.push_back(String(aTmp, eCS));
+                OSL_ENSURE(nLen2 == nLen,
+                    "Fib length and read length are different");
+                if (nLen > USHRT_MAX)
+                    nLen = USHRT_MAX;
+                else if (nLen < 2 )
+                    nLen = 2;
+                nLen2 = static_cast<sal_uInt16>(nLen);
             }
-            else
-                rArray.push_back(aEmptyStr);
-
-            // Skip the extra data (for bVer67 versions this must come from external knowledge)
-            if (nExtraLen)
+            sal_uLong nRead = 0;
+            for( nLen2 -= 2; nRead < nLen2;  )
             {
-                if (pExtraArray)
+                sal_uInt8 nBChar(0);
+                rStrm >> nBChar;
+                ++nRead;
+                if (nBChar)
                 {
-                    ww::bytes extraData;
-                    for(int i =0;i < nExtraLen;i++)
+                    ByteString aTmp;
+                    nRead += SafeReadString(aTmp,nBChar,rStrm);
+                    rArray.push_back(String(aTmp, eCS));
+                }
+                else
+                    rArray.push_back(aEmptyStr);
+
+                // Skip the extra data (for bVer67 versions this must come from
+                // external knowledge)
+                if (nExtraLen)
+                {
+                    if (pExtraArray)
                     {
-                        sal_uInt8 iTmp;
-                        rStrm >> iTmp;
-                        extraData.push_back(iTmp);
+                        ww::bytes extraData;
+                        for (sal_uInt16 i=0;i < nExtraLen;++i)
+                        {
+                            sal_uInt8 iTmp(0);
+                            rStrm >> iTmp;
+                            extraData.push_back(iTmp);
+                        }
+                        pExtraArray->push_back(extraData);
                     }
-                    pExtraArray->push_back(extraData);
+                    else
+                        rStrm.SeekRel( nExtraLen );
+                    nRead+=nExtraLen;
                 }
-                else
-                    rStrm.SeekRel( nExtraLen );
-                nRead+=nExtraLen;
             }
         }
     }
-    rStrm.Seek( nOldPos );
+    rStrm.Seek(nOldPos);
 }
 
 WW8PLCFx_Book::WW8PLCFx_Book(SvStream* pTblSt, const WW8Fib& rFib)
commit a2dc470f1bd045028b020c9a743d881165491aff
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Jul 15 23:23:27 2011 +0100

    defer allocating dest until we know the source exists

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 2a9f8ce..60e1bcd 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -1590,7 +1590,7 @@ void WW8ScannerBase::DeletePieceTable()
 }
 
 WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt,
-    SvStream* pDataSt, const WW8Fib* pWwFib )
+    SvStream* pDataSt, WW8Fib* pWwFib )
     : pWw8Fib(pWwFib), pMainFdoa(0), pHdFtFdoa(0), pMainTxbx(0),
     pMainTxbxBkd(0), pHdFtTxbx(0), pHdFtTxbxBkd(0), pMagicTables(0),
     pSubdocs(0), pExtendedAtrds(0), pPieceGrpprls(0)
@@ -1696,14 +1696,19 @@ 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);
+                sal_Size nOldPos = pTblSt->Tell();
+                if (checkSeek(*pTblSt, pWwFib->fcAtrdExtra))
+                {
+                    pExtendedAtrds = new sal_uInt8[pWwFib->lcbAtrdExtra];
+                    pWwFib->lcbAtrdExtra = pTblSt->Read(pExtendedAtrds,
+                        pWwFib->lcbAtrdExtra);
+                }
+                else
+                    pWwFib->lcbAtrdExtra = 0;
+                pTblSt->Seek(nOldPos);
             }
 
             break;
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 135355e..039b5e3 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -927,7 +927,7 @@ friend class SwWW8FltControlStack;
 #endif
 
 private:
-    const WW8Fib* pWw8Fib;
+    WW8Fib* pWw8Fib;
     WW8PLCFx_Cp_FKP*  pChpPLCF;         // Character-Attrs
     WW8PLCFx_Cp_FKP*  pPapPLCF;         // Para-Attrs
     WW8PLCFx_SEPX*    pSepPLCF;         // Section-Attrs
@@ -963,7 +963,7 @@ private:
     void DeletePieceTable();
 public:
     WW8ScannerBase( SvStream* pSt, SvStream* pTblSt, SvStream* pDataSt,
-        const WW8Fib* pWwF );
+        WW8Fib* pWwF );
     ~WW8ScannerBase();
     bool AreThereFootnotes() const { return pFtnPLCF->Count() > 0; };
     bool AreThereEndnotes()  const { return pEdnPLCF->Count() > 0; };
commit ac85be1a5c89b2e0b8baf1325c38914386b9bb0e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Jul 15 22:17:15 2011 +0100

    horrifically hard to find bug, deleted paras referenced by uncommitted props

diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 104cdfc..750182e 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -3597,6 +3597,7 @@ SwWW8ImplReader::SwWW8ImplReader(sal_uInt8 nVersionPara, SvStorage* pStorage,
     pDataStream(0),
     rDoc(rD),
     maSectionManager(*this),
+    m_aExtraneousParas(rD),
     maInsertedTables(rD),
     maSectionNameGenerator(rD,CREATE_CONST_ASC("WW")),
     maGrfNameGenerator(bNewDoc,String('G')),
@@ -4084,6 +4085,21 @@ void wwSectionManager::InsertSegments()
     }
 }
 
+void wwExtraneousParas::delete_all_from_doc()
+{
+    typedef std::vector<SwTxtNode*>::iterator myParaIter;
+    myParaIter aEnd = m_aTxtNodes.end();
+    for (myParaIter aI = m_aTxtNodes.begin(); aI != aEnd; ++aI)
+    {
+        SwTxtNode *pTxtNode = *aI;
+        SwNodeIndex aIdx(*pTxtNode);
+        SwPosition aPos(aIdx);
+        SwPaM aTest(aPos);
+        m_rDoc.DelFullPara(aTest);
+    }
+    m_aTxtNodes.clear();
+}
+
 void SwWW8ImplReader::StoreMacroCmds()
 {
     if (pWwFib->lcbCmds)
@@ -4711,6 +4727,11 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos)
     DeleteAnchorStk();
     DeleteRefStks();
 
+    //remove extra paragraphs after attribute ctrl
+    //stacks etc. are destroyed, and before fields
+    //are updated
+    m_aExtraneousParas.delete_all_from_doc();
+
     UpdateFields();
 
     // delete the pam before the call for hide all redlines (Bug 73683)
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index df9736a..5a941ba 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -57,6 +57,8 @@
 #include <editeng/lrspitem.hxx>
 #include <oox/ole/olehelper.hxx>
 
+#include <boost/noncopyable.hpp>
+
 class SwDoc;
 class SwPaM;
 class SfxPoolItem;
@@ -839,6 +841,33 @@ public:
     sal_uInt32 GetTextAreaWidth() const;
 };
 
+//Various writer elements like frames start off containing a blank paragraph,
+//sometimes this paragraph turns out to be extraneous, e.g. the frame should
+//only contain a table with no trailing paragraph.
+//
+//We want to remove these extra paragraphs, but removing them during the parse
+//is problematic, because we don't want to remove any paragraphs that are still
+//addressed by property entries in a SwFltControlStack which have not yet been
+//committed to the document.
+//
+//Safest thing is to not delete SwTxtNodes from a document during import, and
+//remove these extraneous paragraphs at the end after all SwFltControlStack are
+//destroyed.
+class wwExtraneousParas : private ::boost::noncopyable
+{
+private:
+    /*
+    A vector of SwTxtNodes to erase from a document after import is complete
+    */
+    std::vector<SwTxtNode*> m_aTxtNodes;
+    SwDoc& m_rDoc;
+public:
+    wwExtraneousParas(SwDoc &rDoc) : m_rDoc(rDoc) {}
+    ~wwExtraneousParas() { delete_all_from_doc(); }
+    void push_back(SwTxtNode *pTxtNode) { m_aTxtNodes.push_back(pTxtNode); }
+    void delete_all_from_doc();
+};
+
 class wwFrameNamer
 {
 private:
@@ -1007,6 +1036,13 @@ private:
     wwSectionManager maSectionManager;
 
     /*
+    A vector of surplus-to-requirements paragraph in the final document,
+    that exist because of quirks of the SwDoc document model and/or API,
+    which need to be removed.
+    */
+    wwExtraneousParas m_aExtraneousParas;
+
+    /*
     A map of of tables to their follow nodes for use in inserting tables into
     already existing document, i.e. insert file
     */
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index ed43304..9870083 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -2272,7 +2272,12 @@ SwTwips SwWW8ImplReader::MoveOutsideFly(SwFrmFmt *pFlyFmt,
                         aIdx++;
                         if (aIdx == aEnd && pNd && !pNd->GetTxt().Len())
                         {
-                            rDoc.DelFullPara( *pPaM );
+                            //An extra pre-created by writer unused paragraph
+                            //
+                            //delete after import is complete rather than now
+                            //to avoid the complication of managing uncommitted
+                            //ctrlstack properties that refer to it.
+                            m_aExtraneousParas.push_back(pNd);
 
                             SwTable& rTable = pTable->GetTable();
                             SwFrmFmt* pTblFmt = rTable.GetFrmFmt();
commit d349886cd73c76f2d01af00d00e170d9d888426e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Jul 14 22:07:08 2011 +0100

    callcatcher: remove unused methods

diff --git a/sw/source/filter/inc/msfilter.hxx b/sw/source/filter/inc/msfilter.hxx
index 68ab860..69885d1 100644
--- a/sw/source/filter/inc/msfilter.hxx
+++ b/sw/source/filter/inc/msfilter.hxx
@@ -318,7 +318,6 @@ namespace sw
         public:
             String msPrimary;
             String msSecondary;
-            bool HasDistinctSecondary() const;
             FontMapExport(const String &rFontDescription);
         };
         
diff --git a/sw/source/filter/ww8/writerwordglue.cxx b/sw/source/filter/ww8/writerwordglue.cxx
index 944bf62..e0cf390 100644
--- a/sw/source/filter/ww8/writerwordglue.cxx
+++ b/sw/source/filter/ww8/writerwordglue.cxx
@@ -467,13 +467,6 @@ namespace sw
                 msSecondary = GetFontToken(rFamilyName, 1);
         }
 
-        bool FontMapExport::HasDistinctSecondary() const
-        {
-            if (msSecondary.Len() && msSecondary != msPrimary)
-                return true;
-            return false;
-        }
-
         bool ItemSort::operator()(sal_uInt16 nA, sal_uInt16 nB) const
         {
             /*


More information about the Libreoffice-commits mailing list