[Libreoffice-commits] core.git: filter/source include/filter sw/CppunitTest_sw_uwriter.mk sw/Library_sw.mk sw/source writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Mar 23 14:46:51 UTC 2018


 filter/source/msfilter/rtfutil.cxx             |   72 +++++++++++++++++++++++++
 include/filter/msfilter/rtfutil.hxx            |   14 ++++
 sw/CppunitTest_sw_uwriter.mk                   |    1 
 sw/Library_sw.mk                               |    1 
 sw/source/filter/html/htmlreqifreader.cxx      |   66 ----------------------
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   53 +-----------------
 writerfilter/source/rtftok/rtftokenizer.cxx    |   21 -------
 writerfilter/source/rtftok/rtftokenizer.hxx    |    1 
 8 files changed, 97 insertions(+), 132 deletions(-)

New commits:
commit 679a3b9314d56cad05b5ff2a2c2fa3d320f719bb
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Mar 23 14:53:44 2018 +0100

    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 at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

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.


More information about the Libreoffice-commits mailing list