diff options
-rw-r--r-- | include/vcl/gdimtf.hxx | 9 | ||||
-rw-r--r-- | include/vcl/metaact.hxx | 6 | ||||
-rw-r--r-- | vcl/qa/cppunit/graphicfilter/data/svm/fail/ofz7165-1.svm | bin | 0 -> 816777 bytes | |||
-rw-r--r-- | vcl/source/gdi/gdimtf.cxx | 40 | ||||
-rw-r--r-- | vcl/source/gdi/metaact.cxx | 4 |
5 files changed, 48 insertions, 11 deletions
diff --git a/include/vcl/gdimtf.hxx b/include/vcl/gdimtf.hxx index d8b8d16e0e60..d455d97e558a 100644 --- a/include/vcl/gdimtf.hxx +++ b/include/vcl/gdimtf.hxx @@ -38,7 +38,7 @@ namespace tools { class PolyPolygon; } class Gradient; - +struct ImplMetaReadData; #define GDI_METAFILE_END ((size_t)0xFFFFFFFF) #define GDI_METAFILE_LABEL_NOTFOUND ((size_t)0xFFFFFFFF) @@ -54,6 +54,9 @@ enum class MtfConversion typedef Color (*ColorExchangeFnc)( const Color& rColor, const void* pColParam ); typedef BitmapEx (*BmpExchangeFnc)( const BitmapEx& rBmpEx, const void* pBmpParam ); +VCL_DLLPUBLIC SvStream& ReadGDIMetaFile(SvStream& rIStm, GDIMetaFile& rGDIMetaFile, ImplMetaReadData* pReadData = nullptr); +VCL_DLLPUBLIC SvStream& WriteGDIMetaFile( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile ); + class VCL_DLLPUBLIC GDIMetaFile final { private: @@ -188,8 +191,8 @@ public: // Stream-operators write (still) the old format // and read both the old and the new format - friend VCL_DLLPUBLIC SvStream& ReadGDIMetaFile( SvStream& rIStm, GDIMetaFile& rGDIMetaFile ); - friend VCL_DLLPUBLIC SvStream& WriteGDIMetaFile( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile ); + friend VCL_DLLPUBLIC SvStream& ReadGDIMetaFile(SvStream& rIStm, GDIMetaFile& rGDIMetaFile, ImplMetaReadData* pReadData); + friend VCL_DLLPUBLIC SvStream& WriteGDIMetaFile(SvStream& rOStm, const GDIMetaFile& rGDIMetaFile); /// Creates an antialiased thumbnail, with maximum width or height of nMaximumExtent. bool CreateThumbnail(BitmapEx& rBitmapEx, diff --git a/include/vcl/metaact.hxx b/include/vcl/metaact.hxx index c7a26cd9727b..ba24042c4ced 100644 --- a/include/vcl/metaact.hxx +++ b/include/vcl/metaact.hxx @@ -43,9 +43,11 @@ enum class DrawTextFlags; struct ImplMetaReadData { rtl_TextEncoding meActualCharSet; + int mnParseDepth; - ImplMetaReadData() : - meActualCharSet( RTL_TEXTENCODING_ASCII_US ) + ImplMetaReadData() + : meActualCharSet(RTL_TEXTENCODING_ASCII_US) + , mnParseDepth(0) {} }; diff --git a/vcl/qa/cppunit/graphicfilter/data/svm/fail/ofz7165-1.svm b/vcl/qa/cppunit/graphicfilter/data/svm/fail/ofz7165-1.svm Binary files differnew file mode 100644 index 000000000000..ad722ea13a6c --- /dev/null +++ b/vcl/qa/cppunit/graphicfilter/data/svm/fail/ofz7165-1.svm diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index 74bdd0747026..42470ef738e6 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -2667,7 +2667,31 @@ sal_uLong GDIMetaFile::GetSizeBytes() const return nSizeBytes; } -SvStream& ReadGDIMetaFile( SvStream& rIStm, GDIMetaFile& rGDIMetaFile ) +namespace +{ + class DepthGuard + { + private: + ImplMetaReadData& m_rData; + rtl_TextEncoding m_eOrigCharSet; + public: + DepthGuard(ImplMetaReadData& rData, SvStream& rIStm) + : m_rData(rData) + , m_eOrigCharSet(m_rData.meActualCharSet) + { + ++m_rData.mnParseDepth; + m_rData.meActualCharSet = rIStm.GetStreamCharSet(); + } + bool TooDeep() const { return m_rData.mnParseDepth > 1024; } + ~DepthGuard() + { + --m_rData.mnParseDepth; + m_rData.meActualCharSet = m_eOrigCharSet; + } + }; +} + +SvStream& ReadGDIMetaFile(SvStream& rIStm, GDIMetaFile& rGDIMetaFile, ImplMetaReadData* pData) { if( !rIStm.GetError() ) { @@ -2695,12 +2719,20 @@ SvStream& ReadGDIMetaFile( SvStream& rIStm, GDIMetaFile& rGDIMetaFile ) pCompat.reset(); // destructor writes stuff into the header - ImplMetaReadData aReadData; - aReadData.meActualCharSet = rIStm.GetStreamCharSet(); + std::unique_ptr<ImplMetaReadData> xReadData; + if (!pData) + { + xReadData.reset(new ImplMetaReadData); + pData = xReadData.get(); + } + DepthGuard aDepthGuard(*pData, rIStm); + + if (aDepthGuard.TooDeep()) + throw std::runtime_error("too much recursion"); for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); nAction++ ) { - MetaAction* pAction = MetaAction::ReadMetaAction( rIStm, &aReadData ); + MetaAction* pAction = MetaAction::ReadMetaAction(rIStm, pData); if( pAction ) { if (pAction->GetType() == MetaActionType::COMMENT) diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index b8169cdb2553..87da241ac7f3 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -3050,10 +3050,10 @@ void MetaFloatTransparentAction::Write( SvStream& rOStm, ImplMetaWriteData* pDat WriteGradient( rOStm, maGradient ); } -void MetaFloatTransparentAction::Read( SvStream& rIStm, ImplMetaReadData* ) +void MetaFloatTransparentAction::Read(SvStream& rIStm, ImplMetaReadData* pData) { VersionCompat aCompat(rIStm, StreamMode::READ); - ReadGDIMetaFile( rIStm, maMtf ); + ReadGDIMetaFile(rIStm, maMtf, pData); ReadPair( rIStm, maPoint ); ReadPair( rIStm, maSize ); ReadGradient( rIStm, maGradient ); |