summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-03-28 08:53:20 +0100
committerMichael Stahl <Michael.Stahl@cib.de>2018-04-04 16:49:52 +0200
commitfc6e9a715c74b2ff74ff9370fe5f5a29e20be8cd (patch)
tree5a3e3f4e7ac2608a37fe3513b3e0fef7f758bb71
parentc4674e8a1b04314fc45f6a8269cf6519b5fc012b (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>
-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 383c7b3de445..ac8fa53e915c 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)
@@ -53,6 +53,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:
@@ -187,8 +190,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
bool CreateThumbnail(BitmapEx& rBitmapEx,
diff --git a/include/vcl/metaact.hxx b/include/vcl/metaact.hxx
index 8fe4f1d43845..0d472dd098f7 100644
--- a/include/vcl/metaact.hxx
+++ b/include/vcl/metaact.hxx
@@ -44,9 +44,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 d339f7f5ff46..7fb6875de148 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -2664,7 +2664,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())
{
@@ -2698,12 +2722,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 1376476634c2..d4b0c1b65f32 100644
--- a/vcl/source/gdi/metaact.cxx
+++ b/vcl/source/gdi/metaact.cxx
@@ -3046,10 +3046,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 );