From 919632bd5e6ab0e7fab1fccb588e9535df64c75d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Wed, 8 Aug 2012 21:39:50 +0100 Subject: [PATCH] validate polypolygon point counts Change-Id: Ibf6bdf48e5855583f14cd2be36f1e4896a396d32 --- svtools/source/filter/wmf/winwmf.cxx | 67 +++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/svtools/source/filter/wmf/winwmf.cxx b/svtools/source/filter/wmf/winwmf.cxx index abcc09bfda08..e2c7421ab47f 100644 --- a/svtools/source/filter/wmf/winwmf.cxx +++ b/svtools/source/filter/wmf/winwmf.cxx @@ -28,6 +28,7 @@ #include "winmtf.hxx" +#include #include #include #include @@ -354,28 +355,55 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc ) case W_META_POLYPOLYGON: { + bool bRecordOk = true; sal_uInt16 nPoly = 0; Point* pPtAry; // Number of polygons: *pWMF >> nPoly; // Number of points of each polygon. Determine total number of points - sal_uInt16* pnPoints = new sal_uInt16[ nPoly ]; + 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 >> pnPoints[i]; + + if (pnPoints[i] > SAL_MAX_UINT16 - nPoints) + { + bRecordOk = false; + break; + } + nPoints += pnPoints[i]; } + + SAL_WARN_IF(!bRecordOk, "svtools", "polypolygon record has more polygons that we can handle"); + + bRecordOk &= pWMF->good(); + + if (!bRecordOk) + { + pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); + break; + } + // Polygon points are: - pPtAry = new Point[nPoints]; + boost::scoped_array xPolygonPoints(new Point[nPoints]); + pPtAry = xPolygonPoints.get(); for (sal_uInt16 i = 0; i < nPoints; i++ ) pPtAry[ i ] = ReadPoint(); + bRecordOk &= pWMF->good(); + + if (!bRecordOk) + { + pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); + break; + } + // Produce PolyPolygon Actions PolyPolygon aPolyPoly( nPoly, pnPoints, pPtAry ); pOut->DrawPolyPolygon( aPolyPoly ); - delete[] pPtAry; - delete[] pnPoints; } break; @@ -1329,16 +1357,43 @@ sal_Bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pSt case W_META_POLYPOLYGON: { + bool bRecordOk = true; sal_uInt16 nPoly, nPoints = 0; *pStm >> nPoly; for(sal_uInt16 i = 0; i < nPoly; i++ ) { - sal_uInt16 nP; + sal_uInt16 nP = 0; *pStm >> nP; - nPoints = nPoints + nP; + if (nP > SAL_MAX_UINT16 - nPoints) + { + bRecordOk = false; + break; + } + nPoints += nP; } + + SAL_WARN_IF(!bRecordOk, "svtools", "polypolygon record has more polygons that we can handle"); + + bRecordOk &= pStm->good(); + + if (!bRecordOk) + { + pStm->SetError( SVSTREAM_FILEFORMAT_ERROR ); + bRet = sal_False; + break; + } + for (sal_uInt16 i = 0; i < nPoints; i++ ) GetWinExtMax( ReadPoint(), rPlaceableBound, nMapMode ); + + bRecordOk &= pStm->good(); + + if (!bRecordOk) + { + pStm->SetError( SVSTREAM_FILEFORMAT_ERROR ); + bRet = sal_False; + break; + } } break;