sw/qa/extras/htmlexport/htmlexport.cxx    |  247 +++++++++++++++---------------
 sw/source/filter/html/htmlreqifreader.cxx |   17 +-
 2 files changed, 147 insertions(+), 117 deletions(-)

New commits:
commit 326c8d06070a4a41a666db919702f7c423dc7a18
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Oct 19 17:53:51 2020 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Oct 20 00:41:26 2020 +0200

    sw reqif-xhtml export, embedded objects: handle non-package Ole10Native 
stream
    
    Commit 1392fd6a7eaf9f507639096984c2a0108f254795 (sw reqif-xhtml export,
    embedded objects: handle Ole10Native stream, 2020-04-30) added support
    for handling an OLE1 stream which contains something other than OLE2
    data.
    
    However, that assumed a fixed class name ("Package") and a matching
    class id. Fix this, similar to how the import side was fixed with commit
    247b247dadc8f0133a8eb94f1423a29315cf998a (sw reqif-xhtml import,
    embedded objects: handle non-package Ole10Native stream, 2020-10-16).
    
    Change-Id: If2ec9434c802e23e395cf2a6eaf63ad5b1db9c1c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104531
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index 8ba6b7e4d160..c96c1c8215b1 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -49,6 +49,78 @@
 #include <docsh.hxx>
 #include <unotxdoc.hxx>
 
+namespace
+{
+/// Test RTF parser that just extracts a single OLE2 object from a file.
+class TestReqIfRtfReader : public SvRTFParser
+{
+public:
+    TestReqIfRtfReader(SvStream& rStream);
+    void NextToken(int nToken) override;
+    bool WriteObjectData(SvStream& rOLE);
+
+private:
+    bool m_bInObjData = false;
+    OStringBuffer m_aHex;
+};
+
+TestReqIfRtfReader::TestReqIfRtfReader(SvStream& rStream)
+    : SvRTFParser(rStream)
+{
+}
+
+void TestReqIfRtfReader::NextToken(int nToken)
+{
+    switch (nToken)
+    {
+        case '}':
+            m_bInObjData = false;
+            break;
+        case RTF_TEXTTOKEN:
+            if (m_bInObjData)
+                m_aHex.append(OUStringToOString(aToken, 
RTL_TEXTENCODING_ASCII_US));
+            break;
+        case RTF_OBJDATA:
+            m_bInObjData = true;
+            break;
+    }
+}
+
+bool TestReqIfRtfReader::WriteObjectData(SvStream& rOLE)
+{
+    OString aObjdata = m_aHex.makeStringAndClear();
+
+    SvMemoryStream aStream;
+    int b = 0;
+    int count = 2;
+
+    // Feed the destination text to a stream.
+    for (int i = 0; i < aObjdata.getLength(); ++i)
+    {
+        char ch = aObjdata[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;
+            }
+        }
+    }
+
+    aStream.Seek(0);
+    rOLE.WriteStream(aStream);
+    return true;
+}
+}
+
 class HtmlExportTest : public SwModelTestBase, public HtmlTestTools
 {
 private:
@@ -141,8 +213,39 @@ private:
 /// HTML export of the sw doc model tests.
 class SwHtmlDomExportTest : public SwModelTestBase, public HtmlTestTools
 {
+public:
+    /// Get the .ole path, assuming maTempFile is an XHTML export result.
+    OUString GetOlePath();
+    /// Parse the ole1 data out of an RTF fragment URL.
+    void ParseOle1FromRtfUrl(const OUString& rRtfUrl, SvMemoryStream& rOle1);
 };
 
+OUString SwHtmlDomExportTest::GetOlePath()
+{
+    SvMemoryStream aStream;
+    HtmlExportTest::wrapFragment(maTempFile, aStream);
+    xmlDocUniquePtr pDoc = parseXmlStream(&aStream);
+    CPPUNIT_ASSERT(pDoc);
+    OUString aOlePath = getXPath(
+        pDoc, 
"/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object", "data");
+    OUString aOleSuffix(".ole");
+    CPPUNIT_ASSERT(aOlePath.endsWith(aOleSuffix));
+    INetURLObject aUrl(maTempFile.GetURL());
+    aUrl.setBase(aOlePath.copy(0, aOlePath.getLength() - 
aOleSuffix.getLength()));
+    aUrl.setExtension("ole");
+    return aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+}
+
+void SwHtmlDomExportTest::ParseOle1FromRtfUrl(const OUString& rRtfUrl, 
SvMemoryStream& rOle1)
+{
+    SvMemoryStream aRtf;
+    HtmlExportTest::wrapRtfFragment(rRtfUrl, aRtf);
+    tools::SvRef<TestReqIfRtfReader> xReader(new TestReqIfRtfReader(aRtf));
+    CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
+    CPPUNIT_ASSERT(xReader->WriteObjectData(rOle1));
+    CPPUNIT_ASSERT(rOle1.Tell());
+}
+
 char const DATA_DIRECTORY[] = "/sw/qa/extras/htmlexport/data/";
 
 DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo81276, "fdo81276.html")
@@ -921,78 +1024,6 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testReqifParagraphAlignment)
     assertXPathNoAttribute(pDoc, "//reqif-xhtml:p", "align");
 }
 
-namespace
-{
-/// Test RTF parser that just extracts a single OLE2 object from a file.
-class TestReqIfRtfReader : public SvRTFParser
-{
-public:
-    TestReqIfRtfReader(SvStream& rStream);
-    void NextToken(int nToken) override;
-    bool WriteObjectData(SvStream& rOLE);
-
-private:
-    bool m_bInObjData = false;
-    OStringBuffer m_aHex;
-};
-
-TestReqIfRtfReader::TestReqIfRtfReader(SvStream& rStream)
-    : SvRTFParser(rStream)
-{
-}
-
-void TestReqIfRtfReader::NextToken(int nToken)
-{
-    switch (nToken)
-    {
-        case '}':
-            m_bInObjData = false;
-            break;
-        case RTF_TEXTTOKEN:
-            if (m_bInObjData)
-                m_aHex.append(OUStringToOString(aToken, 
RTL_TEXTENCODING_ASCII_US));
-            break;
-        case RTF_OBJDATA:
-            m_bInObjData = true;
-            break;
-    }
-}
-
-bool TestReqIfRtfReader::WriteObjectData(SvStream& rOLE)
-{
-    OString aObjdata = m_aHex.makeStringAndClear();
-
-    SvMemoryStream aStream;
-    int b = 0;
-    int count = 2;
-
-    // Feed the destination text to a stream.
-    for (int i = 0; i < aObjdata.getLength(); ++i)
-    {
-        char ch = aObjdata[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;
-            }
-        }
-    }
-
-    aStream.Seek(0);
-    rOLE.WriteStream(aStream);
-    return true;
-}
-}
-
 CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOle1PDF)
 {
     // Save to reqif-xhtml.
@@ -1005,29 +1036,9 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testReqifOle1PDF)
         comphelper::makePropertyValue("FilterOptions", 
OUString("xhtmlns=reqif-xhtml")),
     };
     xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
-
-    // Get the .ole path.
-    SvMemoryStream aStream;
-    HtmlExportTest::wrapFragment(maTempFile, aStream);
-    xmlDocUniquePtr pDoc = parseXmlStream(&aStream);
-    CPPUNIT_ASSERT(pDoc);
-    OUString aOlePath = getXPath(
-        pDoc, 
"/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object", "data");
-    OUString aOleSuffix(".ole");
-    CPPUNIT_ASSERT(aOlePath.endsWith(aOleSuffix));
-    INetURLObject aUrl(maTempFile.GetURL());
-    aUrl.setBase(aOlePath.copy(0, aOlePath.getLength() - 
aOleSuffix.getLength()));
-    aUrl.setExtension("ole");
-    OUString aRtfUrl = aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
-
-    // Parse the ole1 data out of that.
-    SvMemoryStream aRtf;
-    HtmlExportTest::wrapRtfFragment(aRtfUrl, aRtf);
-    tools::SvRef<TestReqIfRtfReader> xReader(new TestReqIfRtfReader(aRtf));
-    CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
+    OUString aRtfUrl = GetOlePath();
     SvMemoryStream aOle1;
-    CPPUNIT_ASSERT(xReader->WriteObjectData(aOle1));
-    CPPUNIT_ASSERT(aOle1.Tell());
+    ParseOle1FromRtfUrl(aRtfUrl, aOle1);
 
     // Check the content of the ole1 data.
     // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
@@ -1116,6 +1127,30 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testReqifOle1Paint)
     // i.e. the "Package" clsid was used on the OLE2 storage unconditionally, 
even for an mspaint
     // case, which has its own clsid.
     CPPUNIT_ASSERT_EQUAL(aExpected.GetHexName(), aActual.GetHexName());
+
+    aStoreProperties = {
+        comphelper::makePropertyValue("FilterName", OUString("HTML 
(StarWriter)")),
+        comphelper::makePropertyValue("FilterOptions", 
OUString("xhtmlns=reqif-xhtml")),
+    };
+    xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
+    OUString aRtfUrl = GetOlePath();
+    SvMemoryStream aOle1;
+    ParseOle1FromRtfUrl(aRtfUrl, aOle1);
+
+    // Check the content of the ole1 data.
+    // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
+    aOle1.Seek(0);
+    sal_uInt32 nData;
+    aOle1.ReadUInt32(nData); // OLEVersion
+    aOle1.ReadUInt32(nData); // FormatID
+    aOle1.ReadUInt32(nData); // ClassName
+    CPPUNIT_ASSERT(nData);
+    OString aClassName = read_uInt8s_ToOString(aOle1, nData - 1);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: PBrush
+    // - Actual  : Package
+    // i.e. a hardcoded class name was written.
+    CPPUNIT_ASSERT_EQUAL(OString("PBrush"), aClassName);
 }
 
 CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testMultiParaListItem)
@@ -1205,29 +1240,9 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testReqifOle1PresDataNoOle2)
         comphelper::makePropertyValue("FilterOptions", 
OUString("xhtmlns=reqif-xhtml")),
     };
     xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
-
-    // Get the .ole path.
-    SvMemoryStream aStream;
-    HtmlExportTest::wrapFragment(maTempFile, aStream);
-    xmlDocUniquePtr pDoc = parseXmlStream(&aStream);
-    CPPUNIT_ASSERT(pDoc);
-    OUString aOlePath = getXPath(
-        pDoc, 
"/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object", "data");
-    OUString aOleSuffix(".ole");
-    CPPUNIT_ASSERT(aOlePath.endsWith(aOleSuffix));
-    INetURLObject aUrl(maTempFile.GetURL());
-    aUrl.setBase(aOlePath.copy(0, aOlePath.getLength() - 
aOleSuffix.getLength()));
-    aUrl.setExtension("ole");
-    OUString aRtfUrl = aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
-
-    // Parse the ole1 data out of the RTF fragment.
-    SvMemoryStream aRtf;
-    HtmlExportTest::wrapRtfFragment(aRtfUrl, aRtf);
-    tools::SvRef<TestReqIfRtfReader> xReader(new TestReqIfRtfReader(aRtf));
-    CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
+    OUString aRtfUrl = GetOlePath();
     SvMemoryStream aOle1;
-    CPPUNIT_ASSERT(xReader->WriteObjectData(aOle1));
-    CPPUNIT_ASSERT(aOle1.Tell());
+    ParseOle1FromRtfUrl(aRtfUrl, aOle1);
 
     // Check the content of the ole1 data.
     // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
diff --git a/sw/source/filter/html/htmlreqifreader.cxx 
b/sw/source/filter/html/htmlreqifreader.cxx
index 2e20e84f06b8..e7b4dece4a41 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -20,6 +20,7 @@
 #include <filter/msfilter/msdffimp.hxx>
 #include <vcl/cvtgrf.hxx>
 #include <ndole.hxx>
+#include <sal/log.hxx>
 
 namespace
 {
@@ -155,7 +156,21 @@ OString InsertOLE1HeaderFromOle10NativeStream(const 
tools::SvRef<SotStorage>& xS
     sal_uInt32 nOle1Size = 0;
     xOle1Stream->ReadUInt32(nOle1Size);
 
-    OString aClassName("Package");
+    OString aClassName;
+    if (xStorage->GetClassName() == SvGlobalName(0x0003000A, 0, 0, 0xc0, 0, 0, 
0, 0, 0, 0, 0x46))
+    {
+        aClassName = "PBrush";
+    }
+    else
+    {
+        if (xStorage->GetClassName()
+            != SvGlobalName(0x0003000C, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 0x46))
+        {
+            SAL_WARN("sw.html", "InsertOLE1HeaderFromOle10NativeStream: 
unexpected class id: "
+                                    << xStorage->GetClassName().GetHexName());
+        }
+        aClassName = "Package";
+    }
 
     // Write ObjectHeader, see [MS-OLEDS] 2.2.4.
     rOle1.Seek(0);
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to