summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-03-28 08:53:20 +0100
committerAndras Timar <andras.timar@collabora.com>2018-04-07 13:23:07 +0200
commit361c09813a685920b6aff33acb4d597bfa663d19 (patch)
tree0f3d0695189de3a547f8dcb2ac400d3362cf1671
parent45638f825464f8341987531da1880cc29a363c91 (diff)
ofz#7165 set a recursion limit for svm in svm
Change-Id: Id9089986012588690b6d5e33cd71d094ef2357dd Reviewed-on: https://gerrit.libreoffice.org/51984 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Stahl <Michael.Stahl@cib.de> (cherry picked from commit fc6e9a715c74b2ff74ff9370fe5f5a29e20be8cd)
-rw-r--r--include/vcl/gdimtf.hxx9
-rw-r--r--include/vcl/metaact.hxx6
-rw-r--r--vcl/qa/cppunit/graphicfilter/data/svm/fail/ofz7165-1.svmbin0 -> 816777 bytes
-rw-r--r--vcl/source/gdi/gdimtf.cxx40
-rw-r--r--vcl/source/gdi/metaact.cxx4
5 files changed, 48 insertions, 11 deletions
diff --git a/include/vcl/gdimtf.hxx b/include/vcl/gdimtf.hxx
index af9547e9b9da..5035c493e6b8 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 3a52aaff98cb..cccbe10345e5 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
new file mode 100644
index 000000000000..ad722ea13a6c
--- /dev/null
+++ b/vcl/qa/cppunit/graphicfilter/data/svm/fail/ofz7165-1.svm
Binary files differ
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index b15b096b05be..cf55c50134f9 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 = 0; ( 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 3ef9692b106a..dc01eec1c2d8 100644
--- a/vcl/source/gdi/metaact.cxx
+++ b/vcl/source/gdi/metaact.cxx
@@ -3042,10 +3042,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 );