[Libreoffice-commits] .: 5 commits - sw/source

Caolán McNamara caolan at kemper.freedesktop.org
Thu Jul 7 04:23:48 PDT 2011


 sw/source/filter/ww8/ww8par3.cxx |   25 ++----
 sw/source/filter/ww8/ww8scan.cxx |  154 +++++++++++++++++++++++----------------
 sw/source/filter/ww8/ww8scan.hxx |   14 ++-
 3 files changed, 107 insertions(+), 86 deletions(-)

New commits:
commit 7b1708cf7f5ab936fd08464099c4854a23574d12
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Jul 7 10:56:19 2011 +0100

    check for short reads

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 57a7096..913a125 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -926,9 +926,9 @@ void WW8SprmIter::UpdateMyMembers()
 
 const sal_uInt8* WW8SprmIter::FindSprm(sal_uInt16 nId)
 {
-    while(GetSprms())
+    while (GetSprms())
     {
-        if( GetAktId() == nId )
+        if (GetAktId() == nId)
             return GetAktParams();              // SPRM found!
         advance();
     }
@@ -1713,7 +1713,7 @@ WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt,
     }
 
     // PLCF fuer TextBox-Stories im Maintext
-    long nLenTxBxS = (8 > pWw8Fib->nVersion) ? 0 : 22;
+    sal_uInt32 nLenTxBxS = (8 > pWw8Fib->nVersion) ? 0 : 22;
     if( pWwFib->fcPlcftxbxTxt && pWwFib->lcbPlcftxbxTxt )
     {
         pMainTxbx = new WW8PLCFspecial( pTblSt, pWwFib->fcPlcftxbxTxt,
@@ -2019,18 +2019,25 @@ xub_StrLen WW8ScannerBase::WW8ReadString( SvStream& rStrm, String& rStr,
 //              WW8PLCFspecial
 //-----------------------------------------
 
-WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, long nFilePos, long nPLCF,
-    long nStruct)
+WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos,
+    sal_uInt32 nPLCF, sal_uInt32 nStruct)
     : nIdx(0), nStru(nStruct)
 {
-    nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
+    const sal_uInt32 nValidMin=4;
+
+    sal_Size nOldPos = pSt->Tell();
+    bool bValid = checkSeek(*pSt, nFilePos);
+    nPLCF = bValid ? std::min(nPLCF, nValidMin) : nValidMin;
+
     // Pointer auf Pos- u. Struct-Array
     pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];
+    pPLCF_PosArray[0] = 0;
 
-    long nOldPos = pSt->Tell();
+    nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
+
+    nPLCF = std::min(nPLCF, nValidMin);
 
-    pSt->Seek( nFilePos );
-    pSt->Read( pPLCF_PosArray, nPLCF );
+    nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
 #ifdef OSL_BIGENDIAN
     for( nIdx = 0; nIdx <= nIMax; nIdx++ )
         pPLCF_PosArray[nIdx] = SWAPLONG( pPLCF_PosArray[nIdx] );
@@ -2041,7 +2048,7 @@ WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, long nFilePos, long nPLCF,
     else
         pPLCF_Contents = 0;                         // kein Inhalt
 
-    pSt->Seek( nOldPos );
+    pSt->Seek(nOldPos);
 }
 
 // WW8PLCFspecial::SeekPos() stellt den WW8PLCFspecial auf die Stelle nPos, wobei auch noch der
@@ -2173,23 +2180,18 @@ WW8PLCF::WW8PLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct,
 
 void WW8PLCF::ReadPLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF )
 {
-    bool failure = false;
-
-    // Pointer auf Pos-Array
-    pPLCF_PosArray = new WW8_CP[ ( nPLCF + 3 ) / 4 ];
-
     sal_Size nOldPos = pSt->Tell();
 
-    pSt->Seek( nFilePos );
-    failure = pSt->GetError();
+    bool bValid = checkSeek(*pSt, nFilePos);
 
-    if (!failure)
+    if (bValid)
     {
-        pSt->Read( pPLCF_PosArray, nPLCF );
-        failure = pSt->GetError();
+        // Pointer auf Pos-Array
+        pPLCF_PosArray = new WW8_CP[ ( nPLCF + 3 ) / 4 ];
+        bValid = checkRead(*pSt, pPLCF_PosArray, nPLCF);
     }
 
-    if (!failure)
+    if (bValid)
     {
 #ifdef OSL_BIGENDIAN
         for( nIdx = 0; nIdx <= nIMax; nIdx++ )
@@ -2200,12 +2202,12 @@ void WW8PLCF::ReadPLCF( SvStream* pSt, WW8_FC nFilePos, sal_Int32 nPLCF )
         pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
     }
 
-    pSt->Seek( nOldPos );
-
-    OSL_ENSURE( !failure, "Document has corrupt PLCF, ignoring it" );
+    OSL_ENSURE(bValid, "Document has corrupt PLCF, ignoring it");
 
-    if (failure)
+    if (!bValid)
         MakeFailedPLCF();
+
+    pSt->Seek(nOldPos);
 }
 
 void WW8PLCF::MakeFailedPLCF()
@@ -2341,16 +2343,23 @@ WW8_CP WW8PLCF::Where() const
 //              WW8PLCFpcd
 //-----------------------------------------
 
-WW8PLCFpcd::WW8PLCFpcd( SvStream* pSt, long nFilePos, long nPLCF, long nStruct )
-    :nStru( nStruct )
+WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos,
+    sal_uInt32 nPLCF, sal_uInt32 nStruct)
+    : nStru( nStruct )
 {
-    nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
+    const sal_uInt32 nValidMin=4;
+
+    sal_Size nOldPos = pSt->Tell();
+    bool bValid = checkSeek(*pSt, nFilePos);
+    nPLCF = bValid ? std::min(nPLCF, nValidMin) : nValidMin;
+
     pPLCF_PosArray = new sal_Int32[ ( nPLCF + 3 ) / 4 ];    // Pointer auf Pos-Array
+    pPLCF_PosArray[0] = 0;
 
-    long nOldPos = pSt->Tell();
+    nPLCF = bValid ? pSt->Read(pPLCF_PosArray, nPLCF) : nValidMin;
+    nPLCF = std::min(nPLCF, nValidMin);
 
-    pSt->Seek( nFilePos );
-    pSt->Read( pPLCF_PosArray, nPLCF );
+    nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
 #ifdef OSL_BIGENDIAN
     for( long nI = 0; nI <= nIMax; nI++ )
       pPLCF_PosArray[nI] = SWAPLONG( pPLCF_PosArray[nI] );
@@ -2565,7 +2574,8 @@ WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(ww::WordVersion eVersion, SvStream* pSt,
                             aEntry.mpData =
                                 new sal_uInt8[aEntry.mnLen + nOrigLen];
                             aEntry.mbMustDelete = true;
-                            pDataSt->Read(aEntry.mpData, aEntry.mnLen);
+                            aEntry.mnLen =
+                                pDataSt->Read(aEntry.mpData, aEntry.mnLen);
 
                             pDataSt->Seek( nCurr );
 
@@ -7311,12 +7321,16 @@ sal_uInt8* wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms,
     while (nLen > (getVersion()?1:0))
     {
         sal_uInt16 nAktId = GetSprmId(pSprms);
-        if (nAktId == nId) // Sprm found
-            return pSprms + DistanceToData(nId);
-
         // gib Zeiger auf Daten
         sal_uInt16 nSize = GetSprmSize(nAktId, pSprms);
-        OSL_ENSURE(nSize <= nLen, "sprm longer than remaining bytes");
+
+        bool bValid = nSize <= nLen;
+
+        OSL_ENSURE(bValid, "sprm longer than remaining bytes");
+
+        if (nAktId == nId && bValid) // Sprm found
+            return pSprms + DistanceToData(nId);
+
         //Clip to available size if wrong
         nSize = std::min(nSize, nLen);
         pSprms += nSize;
@@ -7344,9 +7358,14 @@ SEPr::SEPr() :
     memset(rgdxaColumnWidthSpacing, 0, sizeof(rgdxaColumnWidthSpacing));
 }
 
-bool checkSeek(SvStream &rSt, WW8_FC nOffset)
+bool checkSeek(SvStream &rSt, sal_uInt32 nOffset)
 {
     return (rSt.Seek(nOffset) == static_cast<sal_Size>(nOffset));
 }
 
+bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
+{
+    return (rSt.Read(pDest, nLength) == static_cast<sal_Size>(nLength));
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 2ddb6d5..7cdbb8c 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -218,10 +218,10 @@ private:
     sal_uInt8*  pPLCF_Contents;  ///< Pointer auf Inhalts-Array-Teil des Pos-Array
     long nIMax;             ///< Anzahl der Elemente
     long nIdx;              ///< Merker, wo wir gerade sind
-    long nStru;
+    sal_uInt32 nStru;
 public:
-    WW8PLCFspecial( SvStream* pSt, long nFilePos, long nPLCF,
-        long nStruct );
+    WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos, sal_uInt32 nPLCF,
+        sal_uInt32 nStruct);
     ~WW8PLCFspecial() { delete[] pPLCF_PosArray; }
     long GetIdx() const { return nIdx; }
     void SetIdx( long nI ) { nIdx = nI; }   
@@ -328,9 +328,10 @@ friend class WW8PLCFpcd_Iter;
     sal_Int32* pPLCF_PosArray;  // Pointer auf Pos-Array und auf ganze Struktur
     sal_uInt8*  pPLCF_Contents;  // Pointer auf Inhalts-Array-Teil des Pos-Array
     long nIMax;
-    long nStru;
+    sal_uInt32 nStru;
 public:
-    WW8PLCFpcd( SvStream* pSt, long nFilePos, long nPLCF, long nStruct );
+    WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos, sal_uInt32 nPLCF,
+        sal_uInt32 nStruct);
     ~WW8PLCFpcd(){ delete[] pPLCF_PosArray; }
 };
 
@@ -1780,7 +1781,8 @@ std::vector<sal_uInt8> ChpxToSprms(const Word2CHPX &rChpx);
 
 sal_uLong SafeReadString(ByteString &rStr,sal_uInt16 nLen,SvStream &rStrm);
 
-bool checkSeek(SvStream &rSt, WW8_FC nOffset);
+bool checkSeek(SvStream &rSt, sal_uInt32 nOffset);
+bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength);
 
 //MS has a (slightly) inaccurate view of how many twips
 //are in the default letter size of a page
commit cd1a0417cbde685ce5c889c4002097918df4762f
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jul 6 22:18:32 2011 +0100

    clip nSprmSiz to available data

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index e3be8ca..57a7096 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -3447,7 +3447,7 @@ void WW8PLCFx_SEPX::GetSprms(WW8PLCFxDesc* p)
                 nArrMax = nSprmSiz;                 // Hole mehr Speicher
                 pSprms = new sal_uInt8[nArrMax];
             }
-            pStrm->Read( pSprms, nSprmSiz );        // read Sprms
+            nSprmSiz = pStrm->Read(pSprms, nSprmSiz); // read Sprms
 
             p->nSprmsLen = nSprmSiz;
             p->pMemPos = pSprms;                    // return Position
commit ebcbc63440618c570010daf3abaccaf63660f9c9
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jul 6 22:15:32 2011 +0100

    init some variables against short reads

diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index fffb4e4..e6ec295 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -1065,7 +1065,6 @@ WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
     // Arrays anlegen
     pLFOInfos = new WW8LFOInfos;
     bool bLVLOk = true;
-    sal_uInt8  aBits1;
 
     nLastLFOPosition = USHRT_MAX;
     long nOriginalPos = rSt.Tell();
@@ -1101,7 +1100,7 @@ WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
             for (sal_uInt16 nLevel = 0; nLevel < nMaxLevel; ++nLevel)
                 rSt >> aLST.aIdSty[ nLevel ];
 
-
+            sal_uInt8 aBits1(0);
             rSt >> aBits1;
 
             rSt.SeekRel( 1 );
@@ -1190,12 +1189,6 @@ WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
             bOk = true;
         }
     }
-    if( !bOk )
-    {
-        // Fehler aufgetreten - LSTInfos abraeumen !!!
-
-        ;
-    }
 
     //
     // 2. PLF LFO auslesen und speichern
@@ -1326,13 +1319,15 @@ WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
                 sal_uInt32 nTest;
                 rSt >> nTest;
                 do
+                {
+                    nTest = 0;
                     rSt >> nTest;
+                }
                 while (nTest == 0xFFFFFFFF);
                 rSt.SeekRel(-4);
 
                 std::deque<bool> aNotReallyThere(WW8ListManager::nMaxLevel);
-                sal_uInt8 nLevel = 0;
-                for (nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
+                for (sal_uInt8 nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
                 {
                     WW8LFOLVL aLFOLVL;
                     bLVLOk = false;
@@ -1341,6 +1336,7 @@ WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
                     // 2.2.2.1 den LFOLVL einlesen
                     //
                     rSt >> aLFOLVL.nStartAt;
+                    sal_uInt8 aBits1(0);
                     rSt >> aBits1;
                     rSt.SeekRel( 3 );
                     if (rSt.GetError())
@@ -1402,7 +1398,7 @@ WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
                 //
                 sal_uInt16 aFlagsNewCharFmt = 0;
                 bool bNewCharFmtCreated = false;
-                for (nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
+                for (sal_uInt8 nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
                 {
                     AdjustLVL( nLevel, *pLFOInfo->pNumRule, aItemSet, aCharFmt,
                         bNewCharFmtCreated, sPrefix );
@@ -1412,17 +1408,12 @@ WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
                 //
                 // 2.2.4 ItemPools leeren und loeschen
                 //
-                for (nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
+                for (sal_uInt8 nLevel = 0; nLevel < pLFOInfo->nLfoLvl; ++nLevel)
                     delete aItemSet[ nLevel ];
                 bOk = true;
             }
         }
     }
-    if( !bOk )
-    {
-        // Fehler aufgetreten - LSTInfos und LFOInfos abraeumen !!!
-        ;
-    }
     // und schon sind wir fertig!
     rSt.Seek( nOriginalPos );
 }
commit 3c8049b68d5227b82d646ad63cbaec34eb80248c
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jul 6 22:13:13 2011 +0100

    nStartPos unused

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 2ec78ca..e3be8ca 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -2019,9 +2019,8 @@ xub_StrLen WW8ScannerBase::WW8ReadString( SvStream& rStrm, String& rStr,
 //              WW8PLCFspecial
 //-----------------------------------------
 
-// Bei nStartPos < 0 wird das erste Element des PLCFs genommen
 WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, long nFilePos, long nPLCF,
-    long nStruct, long nStartPos)
+    long nStruct)
     : nIdx(0), nStru(nStruct)
 {
     nIMax = ( nPLCF - 4 ) / ( 4 + nStruct );
@@ -2041,8 +2040,6 @@ WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, long nFilePos, long nPLCF,
         pPLCF_Contents = (sal_uInt8*)&pPLCF_PosArray[nIMax + 1];
     else
         pPLCF_Contents = 0;                         // kein Inhalt
-    if( nStartPos >= 0 )
-        SeekPos( nStartPos );
 
     pSt->Seek( nOldPos );
 }
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 6e76cdc..2ddb6d5 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -221,7 +221,7 @@ private:
     long nStru;
 public:
     WW8PLCFspecial( SvStream* pSt, long nFilePos, long nPLCF,
-        long nStruct, long nStartPos = -1 );
+        long nStruct );
     ~WW8PLCFspecial() { delete[] pPLCF_PosArray; }
     long GetIdx() const { return nIdx; }
     void SetIdx( long nI ) { nIdx = nI; }   
commit 210412187035b77de53cd350b3bfd2cd8400b1eb
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jul 6 16:09:13 2011 +0100

    compare alleged font count with that of font chain

diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 4ea24f7..2ec78ca 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -6196,6 +6196,30 @@ void lcl_checkFontname( String& sString )
     }
 }
 
+namespace
+{
+    sal_uInt16 calcMaxFonts(sal_uInt8 *p, sal_Int32 nFFn)
+    {
+        // Figure out the max number of fonts defined here
+        sal_uInt16 nMax = 0;
+        sal_Int32 nRemaining = nFFn;
+        while (nRemaining)
+        {
+            //p[0] is cbFfnM1, the alleged total length of FFN - 1.
+            sal_uInt16 cbFfnM1 = *p++;
+            --nRemaining;
+
+            if (cbFfnM1 > nRemaining)
+                break;
+
+            nMax++;
+            nRemaining -= cbFfnM1;
+            p += cbFfnM1;
+        }
+        return nMax;
+    }
+}
+
 WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib& rFib )
     : pFontA(0), nMax(0)
 {
@@ -6213,9 +6237,8 @@ WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib& rFib )
     sal_Int32 nFFn = rFib.lcbSttbfffn - 2;
 
     // allocate Font Array
-    sal_uInt8* pA   = new sal_uInt8[ nFFn ];
+    sal_uInt8* pA = new sal_uInt8[nFFn];
     memset(pA, 0, nFFn);
-    WW8_FFN* p = (WW8_FFN*)pA;
 
     ww::WordVersion eVersion = rFib.GetFIBVersion();
 
@@ -6231,34 +6254,23 @@ WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib& rFib )
     rSt.SeekRel( 2 );
 
     // read all font information
-    nFFn = rSt.Read( pA, nFFn );
+    nFFn = rSt.Read(pA, nFFn);
+    sal_uInt16 nCalcMax = calcMaxFonts(pA, nFFn);
 
-    if( eVersion < ww::eWW8 )
+    if (eVersion < ww::eWW8)
+        nMax = nCalcMax;
+    else
     {
-        // try to figure out how many fonts are defined here
-        nMax = 0;
-        long nLeft = nFFn;
-        for(;;)
-        {
-            short nNextSiz;
-
-            nNextSiz = p->cbFfnM1 + 1;
-            if( nNextSiz > nLeft )
-                break;
-            nMax++;
-            nLeft -= nNextSiz;
-            if( nLeft < 1 )     // can we read the given ammount of bytes ?
-                break;
-            // increase p by nNextSiz Bytes
-            p = (WW8_FFN *)( ( (sal_uInt8*)p ) + nNextSiz );
-        }
+        //newer versions include purportive count of fonts, so take min of that
+        //and calced max
+        nMax = std::min(nMax, nCalcMax);
     }
 
     if( nMax )
     {
         // allocate Index Array
         pFontA = new WW8_FFN[ nMax ];
-        p = pFontA;
+        WW8_FFN* p = pFontA;
 
         if( eVersion <= ww::eWW2 )
         {


More information about the Libreoffice-commits mailing list