diff --git a/emfio/inc/mtftools.hxx b/emfio/inc/mtftools.hxx index 6c2f3df102e2..5f0fd268953d 100644 --- a/emfio/inc/mtftools.hxx +++ b/emfio/inc/mtftools.hxx @@ -685,6 +685,9 @@ namespace emfio RasterOp meRasterOp; std::vector< std::unique_ptr > mvGDIObj; + /// Every slot in mvGDIObj below this index holds an object, so the first free one is here + /// or above. + std::size_t mnLowestFreeGDIObj; Point maActPos; WMFRasterOp mnRop; std::vector< std::shared_ptr > mvSaveStack; diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx index be0a7d710dec..11c6268d1574 100644 --- a/emfio/source/reader/mtftools.cxx +++ b/emfio/source/reader/mtftools.cxx @@ -1036,15 +1036,21 @@ namespace emfio } } std::vector>::size_type nIndex; - for ( nIndex = 0; nIndex < mvGDIObj.size(); nIndex++ ) + for ( nIndex = mnLowestFreeGDIObj; nIndex < mvGDIObj.size(); nIndex++ ) { if ( !mvGDIObj[ nIndex ] ) break; } + if ( nIndex > 0xffff ) // the same ceiling an indexed object has + { + SAL_WARN( "emfio", "too many objects" ); + return; + } if ( nIndex == mvGDIObj.size() ) ImplResizeObjectArry( mvGDIObj.size() + 16 ); mvGDIObj[ nIndex ] = std::move(pObject); + mnLowestFreeGDIObj = nIndex + 1; } void MtfTools::CreateObjectIndexed( sal_uInt32 nIndex, std::unique_ptr pObject ) @@ -1089,6 +1095,9 @@ namespace emfio if ( nIndex >= mvGDIObj.size() ) ImplResizeObjectArry( nIndex + 16 ); + if ( !pObject && nIndex < mnLowestFreeGDIObj ) + mnLowestFreeGDIObj = nIndex; + mvGDIObj[ nIndex ] = std::move(pObject); } @@ -1104,6 +1113,8 @@ namespace emfio if ( nIndex < mvGDIObj.size() ) { mvGDIObj[ nIndex ].reset(); + if ( nIndex < mnLowestFreeGDIObj ) + mnLowestFreeGDIObj = nIndex; } } } @@ -1174,6 +1185,7 @@ namespace emfio mnBkMode(BackgroundMode::OPAQUE), meLatestRasterOp(RasterOp::Invert), meRasterOp(RasterOp::OverPaint), + mnLowestFreeGDIObj(0), mnRop(), meGfxMode(GraphicsMode::GM_COMPATIBLE), meMapMode(MappingMode::MM_TEXT),