diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-03-23 14:53:44 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2018-03-23 15:46:25 +0100 |
commit | 679a3b9314d56cad05b5ff2a2c2fa3d320f719bb (patch) | |
tree | 97a949dd4f9ba96b461bb34c4ab1aee16a3871d2 | |
parent | 1ed1753be26325edf3660c9b9cbd76dc0e9d36ce (diff) |
msfilter: extract copy&pasted RTF code from sw and writerfilter
Both the hexdump and the OLE1 reader can be shared.
Change-Id: I97d72a8deeb9c79fc8e8c4a73c613213badfa744
Reviewed-on: https://gerrit.libreoffice.org/51783
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | filter/source/msfilter/rtfutil.cxx | 72 | ||||
-rw-r--r-- | include/filter/msfilter/rtfutil.hxx | 14 | ||||
-rw-r--r-- | sw/CppunitTest_sw_uwriter.mk | 1 | ||||
-rw-r--r-- | sw/Library_sw.mk | 1 | ||||
-rw-r--r-- | sw/source/filter/html/htmlreqifreader.cxx | 66 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.cxx | 53 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtftokenizer.cxx | 21 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtftokenizer.hxx | 1 |
8 files changed, 97 insertions, 132 deletions
diff --git a/filter/source/msfilter/rtfutil.cxx b/filter/source/msfilter/rtfutil.cxx index 31bcffeb4a09..8ac044032163 100644 --- a/filter/source/msfilter/rtfutil.cxx +++ b/filter/source/msfilter/rtfutil.cxx @@ -11,6 +11,9 @@ #include <rtl/strbuf.hxx> #include <osl/diagnose.h> #include <svtools/rtfkeywd.hxx> +#include <rtl/character.hxx> +#include <tools/stream.hxx> +#include <unotools/streamwrap.hxx> namespace msfilter { @@ -182,6 +185,75 @@ OString OutStringUpr(const sal_Char* pToken, const OUString& rStr, rtl_TextEncod aRet.append("}}}"); return aRet.makeStringAndClear(); } + +int AsHex(char ch) +{ + int ret = 0; + if (rtl::isAsciiDigit(static_cast<unsigned char>(ch))) + ret = ch - '0'; + else + { + if (ch >= 'a' && ch <= 'f') + ret = ch - 'a'; + else if (ch >= 'A' && ch <= 'F') + ret = ch - 'A'; + else + return -1; + ret += 10; + } + return ret; +} + +bool ExtractOLE2FromObjdata(const OString& rObjdata, SvStream& rOle2) +{ + SvMemoryStream aStream; + int b = 0, count = 2; + + // Feed the destination text to a stream. + for (int i = 0; i < rObjdata.getLength(); ++i) + { + char ch = rObjdata[i]; + if (ch != 0x0d && ch != 0x0a) + { + b = b << 4; + sal_Int8 parsed = msfilter::rtfutil::AsHex(ch); + if (parsed == -1) + return false; + b += parsed; + count--; + if (!count) + { + aStream.WriteChar(b); + count = 2; + b = 0; + } + } + } + + // Skip ObjectHeader, see [MS-OLEDS] 2.2.4. + if (aStream.Tell()) + { + aStream.Seek(0); + sal_uInt32 nData; + aStream.ReadUInt32(nData); // OLEVersion + aStream.ReadUInt32(nData); // FormatID + aStream.ReadUInt32(nData); // ClassName + aStream.SeekRel(nData); + aStream.ReadUInt32(nData); // TopicName + aStream.SeekRel(nData); + aStream.ReadUInt32(nData); // ItemName + aStream.SeekRel(nData); + aStream.ReadUInt32(nData); // NativeDataSize + + if (nData) + { + rOle2.WriteStream(aStream); + rOle2.Seek(0); + } + } + + return true; +} } } diff --git a/include/filter/msfilter/rtfutil.hxx b/include/filter/msfilter/rtfutil.hxx index 599161670521..48351d382786 100644 --- a/include/filter/msfilter/rtfutil.hxx +++ b/include/filter/msfilter/rtfutil.hxx @@ -20,6 +20,8 @@ // RTF values are often multiplied by 2^16 #define RTF_MULTIPLIER 65536 +class SvStream; + namespace msfilter { namespace rtfutil @@ -52,6 +54,18 @@ MSFILTER_DLLPUBLIC OString OutString(const OUString& rStr, rtl_TextEncoding eDes */ MSFILTER_DLLPUBLIC OString OutStringUpr(const sal_Char* pToken, const OUString& rStr, rtl_TextEncoding eDestEnc); + +/** + * Get the numeric value of a single character, representing a hex value. + * + * @return -1 on failure + */ +MSFILTER_DLLPUBLIC int AsHex(char ch); + +/** + * Extract OLE2 data from an \objdata hex dump. + */ +MSFILTER_DLLPUBLIC bool ExtractOLE2FromObjdata(const OString& rObjdata, SvStream& rOle2); } } diff --git a/sw/CppunitTest_sw_uwriter.mk b/sw/CppunitTest_sw_uwriter.mk index ba31ae9d9a5a..9c305d3dcbb3 100644 --- a/sw/CppunitTest_sw_uwriter.mk +++ b/sw/CppunitTest_sw_uwriter.mk @@ -35,6 +35,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_uwriter, \ i18nlangtag \ i18nutil \ lng \ + msfilter \ oox \ sal \ salhelper \ diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index f70ef0b76b27..78d62e03809e 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -59,6 +59,7 @@ $(eval $(call gb_Library_use_libraries,sw,\ i18nlangtag \ i18nutil \ lng \ + msfilter \ sal \ salhelper \ sax \ diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx index 34199d8a613f..eef33d93b293 100644 --- a/sw/source/filter/html/htmlreqifreader.cxx +++ b/sw/source/filter/html/htmlreqifreader.cxx @@ -14,27 +14,10 @@ #include <svtools/parrtf.hxx> #include <svtools/rtftoken.h> #include <tools/stream.hxx> +#include <filter/msfilter/rtfutil.hxx> namespace { -int AsHex(char ch) -{ - int ret = 0; - if (rtl::isAsciiDigit(static_cast<unsigned char>(ch))) - ret = ch - '0'; - else - { - if (ch >= 'a' && ch <= 'f') - ret = ch - 'a'; - else if (ch >= 'A' && ch <= 'F') - ret = ch - 'A'; - else - return -1; - ret += 10; - } - return ret; -} - /// RTF parser that just extracts a single OLE2 object from a file. class ReqIfRtfReader : public SvRTFParser { @@ -72,52 +55,7 @@ void ReqIfRtfReader::NextToken(int nToken) bool ReqIfRtfReader::WriteObjectData(SvStream& rOLE) { - int b = 0, count = 2; - - SvMemoryStream aBuf; - for (int i = 0; i < m_aHex.getLength(); ++i) - { - char ch = m_aHex[i]; - if (ch != 0x0d && ch != 0x0a) - { - b = b << 4; - sal_Int8 parsed = AsHex(ch); - if (parsed == -1) - return false; - b += parsed; - count--; - if (!count) - { - aBuf.WriteChar(b); - count = 2; - b = 0; - } - } - } - - // Skip ObjectHeader, see [MS-OLEDS] 2.2.4. - if (aBuf.Tell()) - { - aBuf.Seek(0); - sal_uInt32 nData; - aBuf.ReadUInt32(nData); // OLEVersion - aBuf.ReadUInt32(nData); // FormatID - aBuf.ReadUInt32(nData); // ClassName - aBuf.SeekRel(nData); - aBuf.ReadUInt32(nData); // TopicName - aBuf.SeekRel(nData); - aBuf.ReadUInt32(nData); // ItemName - aBuf.SeekRel(nData); - aBuf.ReadUInt32(nData); // NativeDataSize - - if (nData) - { - rOLE.WriteStream(aBuf); - rOLE.Seek(0); - } - } - - return true; + return msfilter::rtfutil::ExtractOLE2FromObjdata(m_aHex.makeStringAndClear(), rOLE); } } diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index d779e18bce71..2e8ff1e9ab78 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -19,6 +19,7 @@ #include <unotools/streamwrap.hxx> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <filter/msfilter/util.hxx> +#include <filter/msfilter/rtfutil.hxx> #include <comphelper/string.hxx> #include <vcl/GraphicObject.hxx> #include <tools/globname.hxx> @@ -816,7 +817,7 @@ void RTFDocumentImpl::resolvePict(bool const bInline, uno::Reference<drawing::XS if (ch != 0x0d && ch != 0x0a && ch != 0x20) { b = b << 4; - sal_Int8 parsed = RTFTokenizer::asHex(ch); + sal_Int8 parsed = msfilter::rtfutil::AsHex(ch); if (parsed == -1) return; b += parsed; @@ -2342,7 +2343,7 @@ RTFError RTFDocumentImpl::popState() if (ch != 0x0d && ch != 0x0a) { b = b << 4; - sal_Int8 parsed = RTFTokenizer::asHex(ch); + sal_Int8 parsed = msfilter::rtfutil::AsHex(ch); if (parsed == -1) return RTFError::HEX_INVALID; b += parsed; @@ -3319,55 +3320,11 @@ RTFError RTFDocumentImpl::popState() RTFError RTFDocumentImpl::handleEmbeddedObject() { - SvMemoryStream aStream; - int b = 0, count = 2; - - // Feed the destination text to a stream. OString aStr = OUStringToOString(m_aStates.top().pDestinationText->makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); - for (int i = 0; i < aStr.getLength(); ++i) - { - char ch = aStr[i]; - if (ch != 0x0d && ch != 0x0a) - { - b = b << 4; - sal_Int8 parsed = RTFTokenizer::asHex(ch); - if (parsed == -1) - return RTFError::HEX_INVALID; - b += parsed; - count--; - if (!count) - { - aStream.WriteChar(b); - count = 2; - b = 0; - } - } - } - std::unique_ptr<SvStream> pStream(new SvMemoryStream()); - - // Skip ObjectHeader, see [MS-OLEDS] 2.2.4. - if (aStream.Tell()) - { - aStream.Seek(0); - sal_uInt32 nData; - aStream.ReadUInt32(nData); // OLEVersion - aStream.ReadUInt32(nData); // FormatID - aStream.ReadUInt32(nData); // ClassName - aStream.SeekRel(nData); - aStream.ReadUInt32(nData); // TopicName - aStream.SeekRel(nData); - aStream.ReadUInt32(nData); // ItemName - aStream.SeekRel(nData); - aStream.ReadUInt32(nData); // NativeDataSize - - if (nData) - { - pStream->WriteStream(aStream); - pStream->Seek(0); - } - } + if (!msfilter::rtfutil::ExtractOLE2FromObjdata(aStr, *pStream)) + return RTFError::HEX_INVALID; uno::Reference<io::XInputStream> xInputStream( new utl::OSeekableInputStreamWrapper(pStream.release(), /*_bOwner=*/true)); diff --git a/writerfilter/source/rtftok/rtftokenizer.cxx b/writerfilter/source/rtftok/rtftokenizer.cxx index d65bda7c2bb7..8ca3a9dade36 100644 --- a/writerfilter/source/rtftok/rtftokenizer.cxx +++ b/writerfilter/source/rtftok/rtftokenizer.cxx @@ -17,6 +17,7 @@ #include "rtfskipdestination.hxx" #include <com/sun/star/io/BufferSizeExceededException.hpp> #include <osl/diagnose.h> +#include <filter/msfilter/rtfutil.hxx> using namespace com::sun::star; @@ -140,7 +141,7 @@ RTFError RTFTokenizer::resolveParse() { SAL_INFO("writerfilter.rtf", OSL_THIS_FUNC << ": hex internal state"); b = b << 4; - sal_Int8 parsed = asHex(ch); + sal_Int8 parsed = msfilter::rtfutil::AsHex(ch); if (parsed == -1) return RTFError::HEX_INVALID; b += parsed; @@ -167,24 +168,6 @@ RTFError RTFTokenizer::resolveParse() return RTFError::OK; } -int RTFTokenizer::asHex(char ch) -{ - int ret = 0; - if (rtl::isAsciiDigit(static_cast<unsigned char>(ch))) - ret = ch - '0'; - else - { - if (ch >= 'a' && ch <= 'f') - ret = ch - 'a'; - else if (ch >= 'A' && ch <= 'F') - ret = ch - 'A'; - else - return -1; - ret += 10; - } - return ret; -} - void RTFTokenizer::pushGroup() { m_nGroup++; } void RTFTokenizer::popGroup() { m_nGroup--; } diff --git a/writerfilter/source/rtftok/rtftokenizer.hxx b/writerfilter/source/rtftok/rtftokenizer.hxx index 21046f462942..d4847e6ed861 100644 --- a/writerfilter/source/rtftok/rtftokenizer.hxx +++ b/writerfilter/source/rtftok/rtftokenizer.hxx @@ -31,7 +31,6 @@ public: ~RTFTokenizer(); RTFError resolveParse(); - static int asHex(char ch); /// Number of states on the stack. int getGroup() const { return m_nGroup; } /// To be invoked by the pushState() callback to signal when the importer enters a group. |