From abb6f47bd3941ec63a41a9b9fa4c7de620b5177d Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Mon, 13 Aug 2012 15:10:02 +0000 Subject: Secured some places where PolyPolygons were created using a all-points count and a all-points array (cherry picked from commit 8ee49906f04106317997e9ca3bb890870816e274) Conflicts: svtools/source/filter/wmf/enhwmf.cxx svtools/source/filter/wmf/winwmf.cxx tools/inc/tools/poly.hxx tools/source/generic/poly2.cxx Change-Id: I57f7f08d8dd87c83c30ab2d16ca22b772b2bd834 --- vcl/source/filter/wmf/enhwmf.cxx | 31 +++++++++++----- vcl/source/filter/wmf/winwmf.cxx | 80 ++++++++++++++++++++++------------------ 2 files changed, 66 insertions(+), 45 deletions(-) (limited to 'vcl') diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx index 560fc9e9366e..9fd8a9f56f92 100644 --- a/vcl/source/filter/wmf/enhwmf.cxx +++ b/vcl/source/filter/wmf/enhwmf.cxx @@ -399,7 +399,7 @@ void EnhWMFReader::ReadAndDrawPolyLine() template void EnhWMFReader::ReadAndDrawPolyPolygon() { - sal_uInt32 i, nPoly, nGesPoints, nPoints; + sal_uInt32 nPoly(0), nGesPoints(0), nReadPoints(0); pWMF->SeekRel( 0x10 ); // Number of polygons *pWMF >> nPoly >> nGesPoints; @@ -410,27 +410,38 @@ void EnhWMFReader::ReadAndDrawPolyPolygon() { // Get number of points in each polygon sal_uInt16 * pnPoints = new sal_uInt16[ nPoly ]; - for ( i = 0; i < nPoly && pWMF->good(); i++ ) + for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i) { + sal_uInt32 nPoints(0); *pWMF >> nPoints; pnPoints[ i ] = (sal_uInt16)nPoints; } if ( pWMF->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( nEndPos - pWMF->Tell() ) ) { // Get polygon points - Point * pPtAry = new Point[ nGesPoints ]; - for ( i = 0; i < nGesPoints && pWMF->good(); i++ ) + PolyPolygon aPolyPoly(nPoly, nPoly); + for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i) { - T nX, nY; - *pWMF >> nX >> nY; - pPtAry[ i ] = Point( nX, nY ); + const sal_uInt16 nPointCount(pnPoints[i]); + Point* pPtAry = new Point[nPointCount]; + for (sal_uInt16 j = 0; j < nPointCount && pWMF->good(); ++j) + { + T nX(0), nY(0); + *pWMF >> nX >> nY; + pPtAry[ i ] = Point( nX, nY ); + ++nReadPoints; + } + + aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); + delete[] pPtAry; } - // Create PolyPolygon Actions - PolyPolygon aPolyPoly( (sal_uInt16)nPoly, pnPoints, pPtAry ); + pOut->DrawPolyPolygon( aPolyPoly, bRecordPath ); - delete[] pPtAry; } delete[] pnPoints; + + OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)"); + } } diff --git a/vcl/source/filter/wmf/winwmf.cxx b/vcl/source/filter/wmf/winwmf.cxx index f16f1d89e36e..84b1a78d9537 100644 --- a/vcl/source/filter/wmf/winwmf.cxx +++ b/vcl/source/filter/wmf/winwmf.cxx @@ -348,54 +348,64 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc ) case W_META_POLYPOLYGON: { bool bRecordOk = true; - sal_uInt16 nPoly = 0; - Point* pPtAry; + sal_uInt16 nPolyCount(0); // Number of polygons: - *pWMF >> nPoly; - // Number of points of each polygon. Determine total number of points - boost::scoped_array xPolygonPointCounts(new sal_uInt16[nPoly]); - sal_uInt16* pnPoints = xPolygonPointCounts.get(); - sal_uInt16 nPoints = 0; - for(sal_uInt16 i = 0; i < nPoly; i++ ) + *pWMF >> nPolyCount; + if (nPolyCount && pWMF->good()) { - *pWMF >> pnPoints[i]; + // Number of points of each polygon. Determine total number of points + boost::scoped_array xPolygonPointCounts(new sal_uInt16[nPolyCount]); + sal_uInt16* pnPoints = xPolygonPointCounts.get(); + PolyPolygon aPolyPoly(nPolyCount, nPolyCount); + sal_uInt16 nPoints = 0; + for (sal_uInt16 a = 0; a < nPolyCount && pWMF->good(); ++a) + { + *pWMF >> pnPoints[a]; + + if (pnPoints[a] > SAL_MAX_UINT16 - nPoints) + { + bRecordOk = false; + break; + } + + nPoints += pnPoints[a]; + } - if (pnPoints[i] > SAL_MAX_UINT16 - nPoints) + SAL_WARN_IF(!bRecordOk, "svtools.filter", "polypolygon record has more polygons than we can handle"); + + bRecordOk &= pWMF->good(); + + if (!bRecordOk) { - bRecordOk = false; + pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); break; } - nPoints += pnPoints[i]; - } - - SAL_WARN_IF(!bRecordOk, "svtools.filter", "polypolygon record has more polygons than we can handle"); + // Polygon points are: + for (sal_uInt16 a = 0; a < nPolyCount && pWMF->good(); ++a) + { + const sal_uInt16 nPointCount(pnPoints[a]); + boost::scoped_array xPolygonPoints(new Point[nPointCount]); + Point* pPtAry = xPolygonPoints.get(); - bRecordOk &= pWMF->good(); + for(sal_uInt16 b(0); b < nPointCount && pWMF->good(); ++b) + { + pPtAry[b] = ReadPoint(); + } - if (!bRecordOk) - { - pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); - break; - } + aPolyPoly.Insert(Polygon(nPointCount, pPtAry)); + } - // Polygon points are: - boost::scoped_array xPolygonPoints(new Point[nPoints]); - pPtAry = xPolygonPoints.get(); - for (sal_uInt16 i = 0; i < nPoints; i++ ) - pPtAry[ i ] = ReadPoint(); + bRecordOk &= pWMF->good(); - bRecordOk &= pWMF->good(); + if (!bRecordOk) + { + pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); + break; + } - if (!bRecordOk) - { - pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); - break; + pOut->DrawPolyPolygon( aPolyPoly ); } - - // Produce PolyPolygon Actions - PolyPolygon aPolyPoly( nPoly, pnPoints, pPtAry ); - pOut->DrawPolyPolygon( aPolyPoly ); } break; -- cgit