summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorofftkp <parisoplop@gmail.com>2022-05-24 16:28:08 +0300
committerTomaž Vajngerl <quikee@gmail.com>2022-06-22 14:16:37 +0200
commit56bfb93d0028b735adaddd7d23be96145a7bd2ed (patch)
tree0a11e51089888b21dfadd69f109e0e9400f5257f /vcl
parenteedc5b1c576fcaaea85a5278762efc8ba8c5a084 (diff)
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 <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/filter/graphicfilter2.cxx64
1 files changed, 58 insertions, 6 deletions
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;
}