[Libreoffice-commits] core.git: Branch 'libreoffice-4-3' - filter/source include/filter sw/source vcl/source

Caolán McNamara caolanm at redhat.com
Thu Oct 23 05:22:03 PDT 2014


 filter/source/graphicfilter/ios2met/ios2met.cxx |   16 +-
 filter/source/graphicfilter/ipcx/ipcx.cxx       |    7 +
 filter/source/msfilter/msdffimp.cxx             |   89 +++++++++----
 filter/source/msfilter/svdfppt.cxx              |    5 
 include/filter/msfilter/svdfppt.hxx             |    2 
 sw/source/filter/ww8/ww8par.cxx                 |   13 +
 vcl/source/filter/wmf/winwmf.cxx                |  159 +++++++++++++++++++-----
 vcl/source/fontsubset/sft.cxx                   |   31 +++-
 8 files changed, 249 insertions(+), 73 deletions(-)

New commits:
commit 22590777ac1fbb1b6dadedae166a59ed3c34dc5b
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Oct 20 09:59:28 2014 +0100

    various untrusted loop bounds
    
    coverity#1242704 Untrusted loop bound
    
    Change-Id: Ib2e00c0cd269dc7ae55b206713fe07e5326072f2
    (cherry picked from commit d615d83381a0830a815fe2879ce761f1b00b04e9)
    
    coverity#1242606 Untrusted loop bound
    
    Change-Id: Iafa03d4dd65eb343a80996880bc1ed846d1b7491
    (cherry picked from commit 1361dfc0aa835dcb134d5de4bac594519aa16efe)
    
    coverity#1242582 Untrusted loop bound
    
    Change-Id: I72d2c4979b62a025d212ce5ee3b7141c40376fa7
    (cherry picked from commit 6118c11a0c5122169979547e8c27136cf58a54a7)
    
    coverity#1242778 Untrusted value as argument
    
    Change-Id: I34d5a5e7c5f0eef51d941c65ab73d5421d5a36cb
    (cherry picked from commit be31503ef86d2ad3291ced8fddb9c4da4d324c46)
    
    coverity#1242724 Untrusted value as argument
    
    Change-Id: I6041d09ef0a4ed4af5f1bf93f31a1eac60be1af7
    (cherry picked from commit bbe264a19fb82f50d859fc72a47312db0527640f)
    
    coverity#1242717 Untrusted loop bound
    
    Change-Id: I983bba075ab9626c90555fa41f9d473ae60fafea
    (cherry picked from commit cf63ebe0f005513c1e989682459bcd0688eb190b)
    
    coverity#1242624 Untrusted loop bound
    
    Change-Id: If2ae1982eec100f5602a13d648beec247ced6aa2
    (cherry picked from commit 711e74544d70b108e9bc70772b31f386dbf1c2a4)
    
    coverity#1222238 Untrusted loop bound
    
    Change-Id: I1a4dec8727d0a27f7fd0396fd22d955f61daaee4
    (cherry picked from commit 5a89092d5fe43638832ea8f86df34f81869337d9)
    
    coverity#1242573 Untrusted loop bound
    
    Change-Id: Id2847c55ccab7272919e76542bc0e0570bc9af12
    (cherry picked from commit 5e2d089f763963e6ce7d3d183bd1bf7932aeaaaf)
    
    coverity#1242573 Untrusted loop bound
    
    (cherry picked from commit 11a514e06bf38c70f2364c8535782aa3f33d6206)
    
    Conflicts:
    	vcl/source/filter/wmf/winwmf.cxx
    
    Change-Id: Ic84e57fbfa2b532409865c4364b91be594d252cf
    
    pass sfntLen to DumpSfnts etc so sfntP reads can be checked
    
    Change-Id: I5d8092eceb31ba251e75fe2c51b87890b8adcbf2
    (cherry picked from commit b4a0104849eeecb7779fda41116c92c362759882)
    
    coverity#1242908 Untrusted value as argument
    
    Change-Id: If9dd92c361d406c435329d29870dc8bb07a8ba7b
    (cherry picked from commit d0be09322d127e7d517851db38c764d57fbab2dc)
    Reviewed-on: https://gerrit.libreoffice.org/12067
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>

diff --git a/filter/source/graphicfilter/ios2met/ios2met.cxx b/filter/source/graphicfilter/ios2met/ios2met.cxx
index aed623e..2b3d25b 100644
--- a/filter/source/graphicfilter/ios2met/ios2met.cxx
+++ b/filter/source/graphicfilter/ios2met/ios2met.cxx
@@ -1010,6 +1010,8 @@ void OS2METReader::ReadChrStr(bool bGivenPos, bool bMove, bool bExtra, sal_uInt1
         else
             nLen = nOrderLen-4;
     }
+    if (nLen > pOS2MET->remainingSize())
+        throw css::uno::Exception("attempt to read past end of input", 0);
     boost::scoped_array<char> pChr(new char[nLen+1]);
     for (i=0; i<nLen; i++)
         pOS2MET->ReadChar( pChr[i] );
@@ -2750,12 +2752,18 @@ GraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
     GDIMetaFile     aMTF;
     bool            bRet = false;
 
-    aOS2METReader.ReadOS2MET( rStream, aMTF );
+    try
+    {
+        aOS2METReader.ReadOS2MET( rStream, aMTF );
 
-    if ( !rStream.GetError() )
+        if ( !rStream.GetError() )
+        {
+            rGraphic=Graphic( aMTF );
+            bRet = true;
+        }
+    }
+    catch (const css::uno::Exception&)
     {
-        rGraphic=Graphic( aMTF );
-        bRet = true;
     }
 
     return bRet;
diff --git a/filter/source/graphicfilter/ipcx/ipcx.cxx b/filter/source/graphicfilter/ipcx/ipcx.cxx
index 32dc0d9..f6fc871 100644
--- a/filter/source/graphicfilter/ipcx/ipcx.cxx
+++ b/filter/source/graphicfilter/ipcx/ipcx.cxx
@@ -222,6 +222,13 @@ void PCXReader::ImplReadBody(BitmapWriteAccess * pAcc)
     sal_uLong   nLastPercent = 0;
     sal_uInt8   nDat = 0, nCol = 0;
 
+    //sanity check there is enough data before trying allocation
+    if (nPlanes > m_rPCX.remainingSize() / nBytesPerPlaneLin)
+    {
+        nStatus = false;
+        return;
+    }
+
     for( np = 0; np < nPlanes; np++ )
         pPlane[ np ] = new sal_uInt8[ nBytesPerPlaneLin ];
 
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index dc72ec7..12ef20a 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -1064,14 +1064,20 @@ void GetShadeColors( const SvxMSDffManager& rManager, const DffPropertyReader& r
     sal_uInt32 nPos = rIn.Tell();
     if ( rProperties.IsProperty( DFF_Prop_fillShadeColors ) )
     {
-        if ( rProperties.SeekToContent( DFF_Prop_fillShadeColors, rIn ) )
+        sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0;
+        bool bOk = false;
+        if (rProperties.SeekToContent(DFF_Prop_fillShadeColors, rIn))
         {
-            sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0;
             rIn.ReadUInt16( nNumElem ).ReadUInt16( nNumElemReserved ).ReadUInt16( nSize );
+            //sanity check that the stream is long enough to fulfill nNumElem * 2 sal_Int32s
+            bOk = rIn.remainingSize() / (2*sizeof(sal_Int32)) >= nNumElem;
+        }
+        if (bOk)
+        {
             for ( ; i < nNumElem; i++ )
             {
-                sal_Int32   nColor;
-                sal_Int32   nDist;
+                sal_Int32 nColor(0);
+                sal_Int32 nDist(0);
 
                 rIn.ReadInt32( nColor ).ReadInt32( nDist );
                 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( nColor, DFF_Prop_fillColor ), 1.0 - ( nDist / 65536.0 ) ) );
@@ -1897,7 +1903,13 @@ void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxIt
             sal_uInt16 nNumElemMem = 0;
             rIn.ReadUInt16( nNumElem ).ReadUInt16( nNumElemMem ).ReadUInt16( nElemSize );
         }
-        if ( nElemSize == 36 )
+        bool bImport = false;
+        if (nElemSize == 36)
+        {
+            //sanity check that the stream is long enough to fulfill nNumElem * nElemSize;
+            bImport = rIn.remainingSize() / nElemSize >= nNumElem;
+        }
+        if (bImport)
         {
             uno::Sequence< beans::PropertyValues > aHandles( nNumElem );
             for ( sal_uInt16 i = 0; i < nNumElem; i++ )
@@ -2309,12 +2321,19 @@ void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxIt
                 sal_uInt16 nNumElemMem = 0;
                 rIn.ReadUInt16( nNumElem ).ReadUInt16( nNumElemMem ).ReadUInt16( nElemSize );
             }
-            if ( nElemSize == 16 )
+            bool bImport = false;
+            if (nElemSize == 16)
+            {
+                //sanity check that the stream is long enough to fulfill nNumElem * nElemSize;
+                bImport = rIn.remainingSize() / nElemSize >= nNumElem;
+            }
+            if (bImport)
             {
-                sal_Int32 nLeft, nTop, nRight, nBottom;
                 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem );
-                for ( sal_uInt16 i = 0; i < nNumElem; i++ )
+                for (sal_uInt16 i = 0; i < nNumElem; ++i)
                 {
+                    sal_Int32 nLeft(0), nTop(0), nRight(0), nBottom(0);
+
                     rIn.ReadInt32( nLeft )
                        .ReadInt32( nTop )
                        .ReadInt32( nRight )
@@ -2342,26 +2361,37 @@ void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxIt
             if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) )
                 rIn.ReadUInt16( nNumElemVert ).ReadUInt16( nNumElemMemVert ).ReadUInt16( nElemSizeVert );
 
-            sal_Int32 nX, nY;
-            sal_Int16 nTmpA, nTmpB;
-            aGluePoints.realloc( nNumElemVert );
-            for ( sal_uInt16 i = 0; i < nNumElemVert; i++ )
+            bool bImport = false;
+            if (nNumElemVert)
             {
-                if ( nElemSizeVert == 8 )
-                {
-                    rIn.ReadInt32( nX )
-                       .ReadInt32( nY );
-                }
-                else
+                //sanity check that the stream is long enough to fulfill nNumElemVert * nElemSizeVert;
+                bImport = rIn.remainingSize() / nElemSizeVert >= nNumElemVert;
+            }
+
+            if (bImport)
+            {
+                aGluePoints.realloc( nNumElemVert );
+                for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
                 {
-                    rIn.ReadInt16( nTmpA )
-                       .ReadInt16( nTmpB );
+                    sal_Int32 nX(0), nY(0);
+                    if ( nElemSizeVert == 8 )
+                    {
+                        rIn.ReadInt32( nX )
+                           .ReadInt32( nY );
+                    }
+                    else
+                    {
+                        sal_Int16 nTmpA(0), nTmpB(0);
 
-                    nX = nTmpA;
-                    nY = nTmpB;
+                        rIn.ReadInt16( nTmpA )
+                           .ReadInt16( nTmpB );
+
+                        nX = nTmpA;
+                        nY = nTmpB;
+                    }
+                    EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First,  nX );
+                    EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
                 }
-                EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First,  nX );
-                EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
             }
             const OUString sGluePoints( "GluePoints" );
             aProp.Name = sGluePoints;
@@ -5319,19 +5349,24 @@ SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
         {
             delete pTextImpRec->pWrapPolygon;
             pTextImpRec->pWrapPolygon = NULL;
-            sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
+            sal_uInt16 nNumElemVert(0), nNumElemMemVert(0), nElemSizeVert(0);
             rSt.ReadUInt16( nNumElemVert ).ReadUInt16( nNumElemMemVert ).ReadUInt16( nElemSizeVert );
+            bool bOk = false;
             if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
             {
+                bOk = rSt.remainingSize() / nElemSizeVert >= nNumElemVert;
+            }
+            if (bOk)
+            {
                 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
                 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
                 {
-                    sal_Int32 nX, nY;
+                    sal_Int32 nX(0), nY(0);
                     if (nElemSizeVert == 8)
                         rSt.ReadInt32( nX ).ReadInt32( nY );
                     else
                     {
-                        sal_Int16 nSmallX, nSmallY;
+                        sal_Int16 nSmallX(0), nSmallY(0);
                         rSt.ReadInt16( nSmallX ).ReadInt16( nSmallY );
                         nX = nSmallX;
                         nY = nSmallY;
diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx
index 7458873..27400f8 100644
--- a/filter/source/msfilter/svdfppt.cxx
+++ b/filter/source/msfilter/svdfppt.cxx
@@ -3841,7 +3841,7 @@ PPTParaSheet::PPTParaSheet( const PPTParaSheet& rSheet )
     *this = rSheet;
 }
 
-void PPTParaSheet::Read( SdrPowerPointImport&
+bool PPTParaSheet::Read( SdrPowerPointImport&
 #ifdef DBG_UTIL
                     rManager
 #endif
@@ -3898,6 +3898,8 @@ void PPTParaSheet::Read( SdrPowerPointImport&
         {
             // number of tabulators
             rIn.ReadUInt16( nVal16 );
+            if (rIn.remainingSize() / sizeof(nVal32) < nVal16)
+                return false;
             for ( i = 0; i < nVal16; i++ )
                 rIn.ReadUInt32( nVal32 );      // reading the tabulators
         }
@@ -3968,6 +3970,7 @@ void PPTParaSheet::Read( SdrPowerPointImport&
         }
         nPMask >>= 1;
     }
+    return true;
 }
 
 void PPTParaSheet::UpdateBulletRelSize(  sal_uInt32 nLevel, sal_uInt16 nFontHeight )
diff --git a/include/filter/msfilter/svdfppt.hxx b/include/filter/msfilter/svdfppt.hxx
index 809b96a..a9bb623 100644
--- a/include/filter/msfilter/svdfppt.hxx
+++ b/include/filter/msfilter/svdfppt.hxx
@@ -791,7 +791,7 @@ public:
                     explicit PPTParaSheet( sal_uInt32 nInstance );
                     PPTParaSheet( const PPTParaSheet& rParaSheet );
 
-    void            Read(
+    bool            Read(
                         SdrPowerPointImport& rMan,
                         SvStream& rIn,
                         bool bMasterStyle,
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 72b24bd..0bf4265 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1039,19 +1039,26 @@ SdrObject* SwMSDffManager::ProcessObj(SvStream& rSt,
             delete pImpRec->pWrapPolygon;
             pImpRec->pWrapPolygon = NULL;
 
-            sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
+            sal_uInt16 nNumElemVert(0), nNumElemMemVert(0), nElemSizeVert(0);
             rSt.ReadUInt16( nNumElemVert ).ReadUInt16( nNumElemMemVert ).ReadUInt16( nElemSizeVert );
+            bool bOk = false;
             if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
             {
+                //check if there is enough data in the file to make the
+                //record sane
+                bOk = rSt.remainingSize() / nElemSizeVert >= nNumElemVert;
+            }
+            if (bOk)
+            {
                 pImpRec->pWrapPolygon = new Polygon(nNumElemVert);
                 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
                 {
-                    sal_Int32 nX, nY;
+                    sal_Int32 nX(0), nY(0);
                     if (nElemSizeVert == 8)
                         rSt.ReadInt32( nX ).ReadInt32( nY );
                     else
                     {
-                        sal_Int16 nSmallX, nSmallY;
+                        sal_Int16 nSmallX(0), nSmallY(0);
                         rSt.ReadInt16( nSmallX ).ReadInt16( nSmallY );
                         nX = nSmallX;
                         nY = nSmallY;
diff --git a/vcl/source/filter/wmf/winwmf.cxx b/vcl/source/filter/wmf/winwmf.cxx
index 4c2c95c..545d09a 100644
--- a/vcl/source/filter/wmf/winwmf.cxx
+++ b/vcl/source/filter/wmf/winwmf.cxx
@@ -328,12 +328,32 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
 
         case W_META_POLYGON:
         {
-            sal_uInt16 nPoints = 0;
-            pWMF->ReadUInt16( nPoints );
-            Polygon aPoly( nPoints );
-            for( sal_uInt16 i = 0; i < nPoints; i++ )
-                aPoly[ i ] = ReadPoint();
-            pOut->DrawPolygon( aPoly );
+            bool bRecordOk = true;
+
+            sal_uInt16 nPoints(0);
+            pWMF->ReadUInt16(nPoints);
+
+            if (nPoints > pWMF->remainingSize() / (2 * sizeof(sal_uInt16)))
+            {
+                bRecordOk = false;
+            }
+            else
+            {
+                Polygon aPoly(nPoints);
+                for (sal_uInt16 i(0); i < nPoints && pWMF->good(); ++i)
+                    aPoly[ i ] = ReadPoint();
+                pOut->DrawPolygon(aPoly);
+            }
+
+            SAL_WARN_IF(!bRecordOk, "vcl.filter", "polygon record has more points than we can handle");
+
+            bRecordOk &= pWMF->good();
+
+            if (!bRecordOk)
+            {
+                pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+                break;
+            }
         }
         break;
 
@@ -403,12 +423,32 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc )
 
         case W_META_POLYLINE:
         {
-            sal_uInt16 nPoints = 0;
-            pWMF->ReadUInt16( nPoints );
-            Polygon aPoly( nPoints );
-            for(sal_uInt16 i = 0; i < nPoints; i++ )
-                aPoly[ i ] = ReadPoint();
-            pOut->DrawPolyLine( aPoly );
+            bool bRecordOk = true;
+
+            sal_uInt16 nPoints(0);
+            pWMF->ReadUInt16(nPoints);
+
+            if (nPoints > pWMF->remainingSize() / (2 * sizeof(sal_uInt16)))
+            {
+                bRecordOk = false;
+            }
+            else
+            {
+                Polygon aPoly(nPoints);
+                for (sal_uInt16 i(0); i < nPoints && pWMF->good(); ++i)
+                    aPoly[ i ] = ReadPoint();
+                pOut->DrawPolyLine( aPoly );
+            }
+
+            SAL_WARN_IF(!bRecordOk, "vcl.filter", "polyline record has more points than we can handle");
+
+            bRecordOk &= pWMF->good();
+
+            if (!bRecordOk)
+            {
+                pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+                break;
+            }
         }
         break;
 
@@ -1449,28 +1489,56 @@ bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pStm )
 
                 case W_META_POLYGON:
                 {
-                    sal_uInt16 nPoints;
+                    bool bRecordOk = true;
+
+                    sal_uInt16 nPoints(0);
                     pStm->ReadUInt16( nPoints );
-                    for(sal_uInt16 i = 0; i < nPoints; i++ )
-                        GetWinExtMax( ReadPoint(), aBound, nMapMode );
+
+                    if (nPoints > pStm->remainingSize() / (2 * sizeof(sal_uInt16)))
+                    {
+                        bRecordOk = false;
+                    }
+                    else
+                    {
+                        for(sal_uInt16 i = 0; i < nPoints; i++ )
+                        {
+                            GetWinExtMax( ReadPoint(), aBound, nMapMode );
+                        }
+                    }
+
+                    SAL_WARN_IF(!bRecordOk, "vcl.wmf", "polyline record claimed more points than the stream can provide");
+
+                    if (!bRecordOk)
+                    {
+                        pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
+                        bRet = false;
+                        break;
+                    }
                 }
                 break;
 
                 case W_META_POLYPOLYGON:
                 {
                     bool bRecordOk = true;
-                    sal_uInt16 nPoly, nPoints = 0;
-                    pStm->ReadUInt16( nPoly );
-                    for(sal_uInt16 i = 0; i < nPoly; i++ )
+                    sal_uInt16 nPoly(0), nPoints(0);
+                    pStm->ReadUInt16(nPoly);
+                    if (nPoly > pStm->remainingSize() / sizeof(sal_uInt16))
+                    {
+                        bRecordOk = false;
+                    }
+                    else
                     {
-                        sal_uInt16 nP = 0;
-                        pStm->ReadUInt16( nP );
-                        if (nP > SAL_MAX_UINT16 - nPoints)
+                        for(sal_uInt16 i = 0; i < nPoly; i++ )
                         {
-                            bRecordOk = false;
-                            break;
+                            sal_uInt16 nP = 0;
+                            pStm->ReadUInt16( nP );
+                            if (nP > SAL_MAX_UINT16 - nPoints)
+                            {
+                                bRecordOk = false;
+                                break;
+                            }
+                            nPoints += nP;
                         }
-                        nPoints += nP;
                     }
 
                     SAL_WARN_IF(!bRecordOk, "vcl.wmf", "polypolygon record has more polygons than we can handle");
@@ -1484,8 +1552,19 @@ bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pStm )
                         break;
                     }
 
-                    for (sal_uInt16 i = 0; i < nPoints; i++ )
-                        GetWinExtMax( ReadPoint(), aBound, nMapMode );
+                    if (nPoints > pStm->remainingSize() / (2 * sizeof(sal_uInt16)))
+                    {
+                        bRecordOk = false;
+                    }
+                    else
+                    {
+                        for (sal_uInt16 i = 0; i < nPoints; i++ )
+                        {
+                            GetWinExtMax( ReadPoint(), aBound, nMapMode );
+                        }
+                    }
+
+                    SAL_WARN_IF(!bRecordOk, "vcl.wmf", "polypolygon record claimed more points than the stream can provide");
 
                     bRecordOk &= pStm->good();
 
@@ -1500,10 +1579,30 @@ bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pStm )
 
                 case W_META_POLYLINE:
                 {
-                    sal_uInt16 nPoints;
-                    pStm->ReadUInt16( nPoints );
-                    for(sal_uInt16 i = 0; i < nPoints; i++ )
-                        GetWinExtMax( ReadPoint(), aBound, nMapMode );
+                    bool bRecordOk = true;
+
+                    sal_uInt16 nPoints(0);
+                    pStm->ReadUInt16(nPoints);
+                    if (nPoints > pStm->remainingSize() / (2 * sizeof(sal_uInt16)))
+                    {
+                        bRecordOk = false;
+                    }
+                    else
+                    {
+                        for (sal_uInt16 i = 0; i < nPoints; ++i)
+                        {
+                            GetWinExtMax( ReadPoint(), aBound, nMapMode );
+                        }
+                    }
+
+                    SAL_WARN_IF(!bRecordOk, "vcl.wmf", "polyline record claimed more points than the stream can provide");
+
+                    if (!bRecordOk)
+                    {
+                        pStm->SetError( SVSTREAM_FILEFORMAT_ERROR );
+                        bRet = false;
+                        break;
+                    }
                 }
                 break;
 
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index a72627b..9cc8811 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -2027,7 +2027,7 @@ int  CreateTTFromTTGlyphs(TrueTypeFont  *ttf,
 #endif
 
 #ifndef NO_TYPE42
-static GlyphOffsets *GlyphOffsetsNew(sal_uInt8 *sfntP)
+static GlyphOffsets *GlyphOffsetsNew(sal_uInt8 *sfntP, sal_uInt32 sfntLen)
 {
     GlyphOffsets* res = (GlyphOffsets*)smalloc(sizeof(GlyphOffsets));
     sal_uInt8 *loca = NULL;
@@ -2035,10 +2035,27 @@ static GlyphOffsets *GlyphOffsetsNew(sal_uInt8 *sfntP)
     sal_uInt32 locaLen = 0;
     sal_Int16 indexToLocFormat = 0;
 
+    sal_uInt32 nMaxPossibleTables = sfntLen / (3*sizeof(sal_uInt32)); /*the three GetUInt32 calls*/
+    if (numTables > nMaxPossibleTables)
+    {
+        SAL_WARN( "vcl.fonts", "GlyphOffsetsNew claimed to have "
+            << numTables  << " tables, but that's impossibly large");
+        numTables = nMaxPossibleTables;
+    }
+
     for (i = 0; i < numTables; i++) {
-        sal_uInt32 tag = GetUInt32(sfntP + 12, 16 * i, 1);
-        sal_uInt32 off = GetUInt32(sfntP + 12, 16 * i + 8, 1);
-        sal_uInt32 len = GetUInt32(sfntP + 12, 16 * i + 12, 1);
+        sal_uInt32 nLargestFixedOffsetPos = 12 + 16 * i + 12;
+        sal_uInt32 nMinSize = nLargestFixedOffsetPos + sizeof(sal_uInt32);
+        if (nMinSize > sfntLen)
+        {
+            SAL_WARN( "vcl.fonts", "GlyphOffsetsNew claimed to have "
+                << numTables  << " tables, but only space for " << i);
+            break;
+        }
+
+        sal_uInt32 tag = GetUInt32(sfntP, 12 + 16 * i, 1);
+        sal_uInt32 off = GetUInt32(sfntP, 12 + 16 * i + 8, 1);
+        sal_uInt32 len = GetUInt32(sfntP, nLargestFixedOffsetPos, 1);
 
         if (tag == T_loca) {
             loca = sfntP + off;
@@ -2070,11 +2087,11 @@ static void GlyphOffsetsDispose(GlyphOffsets *_this)
     }
 }
 
-static void DumpSfnts(FILE *outf, sal_uInt8 *sfntP)
+static void DumpSfnts(FILE *outf, sal_uInt8 *sfntP, sal_uInt32 sfntLen)
 {
     HexFmt *h = HexFmtNew(outf);
     sal_uInt16 i, numTables = GetUInt16(sfntP, 4, 1);
-    GlyphOffsets *go = GlyphOffsetsNew(sfntP);
+    GlyphOffsets *go = GlyphOffsetsNew(sfntP, sfntLen);
     sal_uInt8 pad[] = {0,0,0,0};                     /* zeroes                       */
 
     assert(numTables <= 9);                                 /* Type42 has 9 required tables */
@@ -2208,7 +2225,7 @@ int  CreateT42FromTTGlyphs(TrueTypeFont  *ttf,
     }
     fprintf(outf, "/XUID [103 0 1 16#%08X %d 16#%08X 16#%08X] def\n", (unsigned int)rtl_crc32(0, ttf->ptr, ttf->fsize), (unsigned int)nGlyphs, (unsigned int)rtl_crc32(0, glyphArray, nGlyphs * 2), (unsigned int)rtl_crc32(0, encoding, nGlyphs));
 
-    DumpSfnts(outf, sfntP);
+    DumpSfnts(outf, sfntP, sfntLen);
 
     /* dump charstrings */
     fprintf(outf, "/CharStrings %d dict dup begin\n", nGlyphs);


More information about the Libreoffice-commits mailing list