summaryrefslogtreecommitdiff
path: root/emfio
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-11-14 09:47:57 +0000
committerCaolán McNamara <caolanm@redhat.com>2017-11-14 13:25:36 +0100
commit7d6f8b48ad4131b13f18ce9d92c10f6b998a68ec (patch)
tree60f5d05fbe713629e3a3b03de3835fc99c270ec0 /emfio
parent36e0acffbe2759dd2a910d2393f266c5c4898786 (diff)
ofz: stop at min of end of record and end of stream
Change-Id: I61c7cf74ea75ec56b6ccb3661f6fdd54a1ff12e1 Reviewed-on: https://gerrit.libreoffice.org/44705 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'emfio')
-rw-r--r--emfio/inc/emfreader.hxx8
-rw-r--r--emfio/source/reader/emfreader.cxx63
2 files changed, 41 insertions, 30 deletions
diff --git a/emfio/inc/emfreader.hxx b/emfio/inc/emfreader.hxx
index 4b2855cf54f6..a54eee1a9c70 100644
--- a/emfio/inc/emfreader.hxx
+++ b/emfio/inc/emfreader.hxx
@@ -44,10 +44,10 @@ namespace emfio
bool ReadEnhWMF();
private:
- template <class T> void ReadAndDrawPolyPolygon();
- template <class T> void ReadAndDrawPolyLine();
- template <class T> tools::Polygon ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints);
- template <class T> tools::Polygon ReadPolygonWithSkip(const bool skipFirst);
+ template <class T> void ReadAndDrawPolyPolygon(sal_uInt32 nNextPos);
+ template <class T> void ReadAndDrawPolyLine(sal_uInt32 nNextPos);
+ template <class T> tools::Polygon ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints, sal_uInt32 nNextPos);
+ template <class T> tools::Polygon ReadPolygonWithSkip(const bool skipFirst, sal_uInt32 nNextPos);
tools::Rectangle ReadRectangle();
void ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC);
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index bcd8b7a83855..6ee222d427cb 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -468,7 +468,7 @@ namespace emfio
* skipFirst: if the first point read is the 0th point or the 1st point in the array.
* */
template <class T>
- tools::Polygon EmfReader::ReadPolygonWithSkip(const bool skipFirst)
+ tools::Polygon EmfReader::ReadPolygonWithSkip(const bool skipFirst, sal_uInt32 nNextPos)
{
sal_uInt32 nPoints(0), nStartIndex(0);
mpInputStream->SeekRel( 16 );
@@ -479,7 +479,7 @@ namespace emfio
nStartIndex ++;
}
- return ReadPolygon<T>(nStartIndex, nPoints);
+ return ReadPolygon<T>(nStartIndex, nPoints, nNextPos);
}
/**
@@ -490,13 +490,22 @@ namespace emfio
* mpInputStream: the stream containing the polygons
* */
template <class T>
- tools::Polygon EmfReader::ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints)
+ tools::Polygon EmfReader::ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints, sal_uInt32 nNextPos)
{
bool bRecordOk = nPoints <= SAL_MAX_UINT16;
SAL_WARN_IF(!bRecordOk, "emfio", "polygon record has more polygons than we can handle");
if (!bRecordOk)
return tools::Polygon();
+ auto nRemainingSize = std::min(nNextPos - mpInputStream->Tell(), mpInputStream->remainingSize());
+ auto nMaxPossiblePoints = nRemainingSize / (sizeof(T) * 2);
+ auto nPointCount = nPoints - nStartIndex;
+ if (nPointCount > nMaxPossiblePoints)
+ {
+ SAL_WARN("emfio", "polygon claims more points than record can provide, truncating");
+ nPoints = nMaxPossiblePoints + nStartIndex;
+ }
+
tools::Polygon aPolygon(nPoints);
for (sal_uInt32 i = nStartIndex ; i < nPoints && mpInputStream->good(); i++ )
{
@@ -519,20 +528,21 @@ namespace emfio
* The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
* */
template <class T>
- void EmfReader::ReadAndDrawPolyLine()
+ void EmfReader::ReadAndDrawPolyLine(sal_uInt32 nNextPos)
{
sal_uInt32 nPoints;
sal_uInt32 i, nNumberOfPolylines( 0 ), nCount( 0 );
mpInputStream->SeekRel( 0x10 ); // TODO Skipping Bounds. A 128-bit WMF RectL object (specifies the bounding rectangle in device units.)
mpInputStream->ReadUInt32( nNumberOfPolylines );
mpInputStream->ReadUInt32( nCount ); // total number of points in all polylines
- if (mpInputStream->Tell() >= mnEndPos)
+ const auto nEndPos = std::min(nNextPos, mnEndPos);
+ if (mpInputStream->Tell() >= nEndPos)
return;
// taking the amount of points of each polygon, retrieving the total number of points
if ( mpInputStream->good() &&
( nNumberOfPolylines < SAL_MAX_UINT32 / sizeof( sal_uInt16 ) ) &&
- ( nNumberOfPolylines * sizeof( sal_uInt16 ) ) <= ( mnEndPos - mpInputStream->Tell() )
+ ( nNumberOfPolylines * sizeof( sal_uInt16 ) ) <= ( nEndPos - mpInputStream->Tell() )
)
{
std::unique_ptr< sal_uInt32[] > pnPolylinePointCount( new sal_uInt32[ nNumberOfPolylines ] );
@@ -544,8 +554,8 @@ namespace emfio
// Get polyline points:
for ( i = 0; ( i < nNumberOfPolylines ) && mpInputStream->good(); i++ )
{
- tools::Polygon aPolygon = ReadPolygon< T >( 0, pnPolylinePointCount[ i ] );
- DrawPolyLine( aPolygon, false, mbRecordPath);
+ tools::Polygon aPolygon = ReadPolygon<T>(0, pnPolylinePointCount[i], nNextPos);
+ DrawPolyLine(aPolygon, false, mbRecordPath);
}
}
}
@@ -555,13 +565,14 @@ namespace emfio
* The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
* */
template <class T>
- void EmfReader::ReadAndDrawPolyPolygon()
+ void EmfReader::ReadAndDrawPolyPolygon(sal_uInt32 nNextPos)
{
sal_uInt32 nPoly(0), nGesPoints(0), nReadPoints(0);
mpInputStream->SeekRel( 0x10 );
// Number of polygons
mpInputStream->ReadUInt32( nPoly ).ReadUInt32( nGesPoints );
- if (mpInputStream->Tell() >= mnEndPos)
+ const auto nEndPos = std::min(nNextPos, mnEndPos);
+ if (mpInputStream->Tell() >= nEndPos)
return;
if (!mpInputStream->good())
return;
@@ -570,7 +581,7 @@ namespace emfio
return;
if (nPoly >= SAL_MAX_UINT32 / sizeof(sal_uInt16))
return;
- if (nPoly * sizeof(sal_uInt16) > mnEndPos - mpInputStream->Tell())
+ if (nPoly * sizeof(sal_uInt16) > nEndPos - mpInputStream->Tell())
return;
// Get number of points in each polygon
@@ -581,7 +592,7 @@ namespace emfio
mpInputStream->ReadUInt32( nPoints );
aPoints[i] = (sal_uInt16)nPoints;
}
- if ( mpInputStream->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( mnEndPos - mpInputStream->Tell() ) )
+ if ( mpInputStream->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( nEndPos - mpInputStream->Tell() ) )
{
// Get polygon points
tools::PolyPolygon aPolyPoly(nPoly, nPoly);
@@ -706,30 +717,30 @@ namespace emfio
switch( nRecType )
{
case EMR_POLYBEZIERTO :
- DrawPolyBezier(ReadPolygonWithSkip<sal_Int32>(true), true, mbRecordPath);
+ DrawPolyBezier(ReadPolygonWithSkip<sal_Int32>(true, nNextPos), true, mbRecordPath);
break;
case EMR_POLYBEZIER :
- DrawPolyBezier(ReadPolygonWithSkip<sal_Int32>(false), false, mbRecordPath);
+ DrawPolyBezier(ReadPolygonWithSkip<sal_Int32>(false, nNextPos), false, mbRecordPath);
break;
case EMR_POLYGON :
- DrawPolygon(ReadPolygonWithSkip<sal_Int32>(false), mbRecordPath);
+ DrawPolygon(ReadPolygonWithSkip<sal_Int32>(false, nNextPos), mbRecordPath);
break;
case EMR_POLYLINETO :
- DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(true), true, mbRecordPath);
+ DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(true, nNextPos), true, mbRecordPath);
break;
case EMR_POLYLINE :
- DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(false), false, mbRecordPath);
+ DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(false, nNextPos), false, mbRecordPath);
break;
case EMR_POLYPOLYLINE :
- ReadAndDrawPolyLine<sal_Int32>();
+ ReadAndDrawPolyLine<sal_Int32>(nNextPos);
break;
case EMR_POLYPOLYGON :
- ReadAndDrawPolyPolygon<sal_Int32>();
+ ReadAndDrawPolyPolygon<sal_Int32>(nNextPos);
break;
case EMR_SETWINDOWEXTEX :
@@ -1649,31 +1660,31 @@ namespace emfio
break;
case EMR_POLYBEZIERTO16 :
- DrawPolyBezier(ReadPolygonWithSkip<sal_Int16>(true), true, mbRecordPath);
+ DrawPolyBezier(ReadPolygonWithSkip<sal_Int16>(true, nNextPos), true, mbRecordPath);
break;
case EMR_POLYBEZIER16 :
- DrawPolyBezier(ReadPolygonWithSkip<sal_Int16>(false), false, mbRecordPath);
+ DrawPolyBezier(ReadPolygonWithSkip<sal_Int16>(false, nNextPos), false, mbRecordPath);
break;
case EMR_POLYGON16 :
- DrawPolygon(ReadPolygonWithSkip<sal_Int16>(false), mbRecordPath);
+ DrawPolygon(ReadPolygonWithSkip<sal_Int16>(false, nNextPos), mbRecordPath);
break;
case EMR_POLYLINETO16 :
- DrawPolyLine(ReadPolygonWithSkip<sal_Int16>(true), true, mbRecordPath);
+ DrawPolyLine(ReadPolygonWithSkip<sal_Int16>(true, nNextPos), true, mbRecordPath);
break;
case EMR_POLYLINE16 :
- DrawPolyLine(ReadPolygonWithSkip<sal_Int16>(false), false, mbRecordPath);
+ DrawPolyLine(ReadPolygonWithSkip<sal_Int16>(false, nNextPos), false, mbRecordPath);
break;
case EMR_POLYPOLYLINE16 :
- ReadAndDrawPolyLine<sal_Int16>();
+ ReadAndDrawPolyLine<sal_Int16>(nNextPos);
break;
case EMR_POLYPOLYGON16 :
- ReadAndDrawPolyPolygon<sal_Int16>();
+ ReadAndDrawPolyPolygon<sal_Int16>(nNextPos);
break;
case EMR_FILLRGN :