diff options
author | offtkp <parisoplop@gmail.com> | 2022-05-24 16:28:08 +0300 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2022-06-22 14:16:37 +0200 |
commit | 56bfb93d0028b735adaddd7d23be96145a7bd2ed (patch) | |
tree | 0a11e51089888b21dfadd69f109e0e9400f5257f /vcl | |
parent | eedc5b1c576fcaaea85a5278762efc8ba8c5a084 (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.cxx | 64 |
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; } |