vcl/source/filter/graphicfilter2.cxx |   64 +++++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 6 deletions(-)

New commits:
commit 56bfb93d0028b735adaddd7d23be96145a7bd2ed
Author:     offtkp <parisop...@gmail.com>
AuthorDate: Tue May 24 16:28:08 2022 +0300
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Wed Jun 22 14:16:37 2022 +0200

    Detect WMF from header instead of extension
    
    Change ImpDetectWMF function to detect a WMF file
    from its header instead of just comparing the extension.
    
    Change-Id: I5a31cfd52b5425ab94424c2edce842365db04e8c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134876
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/vcl/source/filter/graphicfilter2.cxx 
b/vcl/source/filter/graphicfilter2.cxx
index c02e9d557c44..fb001ee14a25 100644
--- a/vcl/source/filter/graphicfilter2.cxx
+++ b/vcl/source/filter/graphicfilter2.cxx
@@ -30,9 +30,24 @@
 #include "graphicfilter_internal.hxx"
 
 #define DATA_SIZE           640
-constexpr sal_uInt32 EMF_CHECK_SIZE    = 44;
-constexpr sal_uInt32 EMR_HEADER        = 0x00000001;
-constexpr sal_uInt32 ENHMETA_SIGNATURE = 0x464d4520;
+constexpr sal_uInt32 EMF_CHECK_SIZE      = 44;
+constexpr sal_uInt32 WMF_CHECK_SIZE      = 32;
+constexpr sal_uInt32 EMR_HEADER          = 0x00000001;
+constexpr sal_uInt32 ENHMETA_SIGNATURE   = 0x464d4520;
+constexpr sal_uInt32 PLACEABLE_SIGNATURE = 0xd7cdc69a;
+namespace
+{
+enum class MetafileType : sal_uInt16
+{
+    Memory = 0x0001,
+    Disk   = 0x0002,
+};
+enum class MetafileVersion : sal_uInt16
+{
+    Version100 = 0x0100,
+    Version300 = 0x0300,
+};
+}
 
 GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) :
     pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( 
INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ).release() ),
@@ -1081,12 +1096,49 @@ bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, 
bool bExtendedInfo )
     return bRet;
 }
 
-bool GraphicDescriptor::ImpDetectWMF( SvStream&, bool )
+bool GraphicDescriptor::ImpDetectWMF(SvStream& rStm, bool)
 {
-    bool bRet = aPathExt.startsWith( "wmf" ) || aPathExt.startsWith( "wmz" );
-    if (bRet)
+    bool bRet = false;
+    SvStream* aNewStream = &rStm;
+    SvMemoryStream aMemStream;
+    sal_uInt8 aUncompressedBuffer[WMF_CHECK_SIZE];
+    if (ZCodec::IsZCompressed(rStm))
+    {
+        ZCodec aCodec;
+        aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/ true);
+        auto nDecompressLength = aCodec.Read(rStm, aUncompressedBuffer, 
WMF_CHECK_SIZE);
+        aCodec.EndCompression();
+        if (nDecompressLength != WMF_CHECK_SIZE)
+            return false;
+        aMemStream.SetBuffer(aUncompressedBuffer, WMF_CHECK_SIZE, 
WMF_CHECK_SIZE);
+        aNewStream = &aMemStream;
+    }
+    sal_uInt32 nKey = 0;
+    sal_Int32 nStmPos = rStm.Tell();
+    aNewStream->SetEndian(SvStreamEndian::LITTLE);
+    aNewStream->ReadUInt32(nKey);
+    // Check if file is placeable WMF
+    if (nKey == PLACEABLE_SIGNATURE)
+    {
         nFormat = GraphicFileFormat::WMF;
+        bRet = true;
+    }
+    else
+    {
+        sal_uInt16 nKeyLSW = nKey & 0xFFFF;
+        sal_uInt16 nVersion = 0;
+        aNewStream->ReadUInt16(nVersion);
+        if ((nKeyLSW == static_cast<sal_uInt16>(MetafileType::Memory)
+            || nKeyLSW == static_cast<sal_uInt16>(MetafileType::Disk))
+            && (nVersion == 
static_cast<sal_uInt16>(MetafileVersion::Version100)
+            || nVersion == 
static_cast<sal_uInt16>(MetafileVersion::Version300)))
+        {
+            nFormat = GraphicFileFormat::WMF;
+            bRet = true;
+        }
+    }
 
+    rStm.Seek(nStmPos);
     return bRet;
 }
 

Reply via email to