sw/qa/extras/htmlexport/data/reqif-ole-nodata.odt |binary
 sw/qa/extras/htmlexport/htmlexport.cxx            |   36 +++++++++--
 sw/source/filter/html/htmlplug.cxx                |   72 ++++++++++++++++------
 3 files changed, 86 insertions(+), 22 deletions(-)

New commits:
commit 5d997c029e53c31a3651a08f5012645097cec48f
Author:     Miklos Vajna <vmik...@collabora.co.uk>
AuthorDate: Thu Aug 30 14:14:11 2018 +0200
Commit:     Miklos Vajna <vmik...@collabora.co.uk>
CommitDate: Thu Aug 30 18:43:08 2018 +0200

    sw XHTML export: improve dummy OLE object handling
    
    It is possible that we not only have a dummy OLE object, but both the
    replacement image and the native data is missing. Handle these enough so
    that we don't give up exporting the document and also produce valid
    output.
    
    Change-Id: Ia973ecfbfb7e8fdecdc831b29d3a82c988ed7ea5
    Reviewed-on: https://gerrit.libreoffice.org/59806
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/htmlexport/data/reqif-ole-nodata.odt 
b/sw/qa/extras/htmlexport/data/reqif-ole-nodata.odt
new file mode 100644
index 000000000000..a4d3243a8bf3
Binary files /dev/null and b/sw/qa/extras/htmlexport/data/reqif-ole-nodata.odt 
differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index 696ca6041dad..c83170752496 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -35,6 +35,20 @@ public:
         m_eUnit(FUNIT_NONE)
     {}
 
+    /**
+     * Wraps a reqif-xhtml fragment into an XHTML file, so an XML parser can
+     * parse it.
+     */
+    void wrapFragment(SvMemoryStream& rStream)
+    {
+        rStream.WriteCharPtr(
+            "<reqif-xhtml:html 
xmlns:reqif-xhtml=\"http://www.w3.org/1999/xhtml\";>\n");
+        SvFileStream aFileStream(maTempFile.GetURL(), StreamMode::READ);
+        rStream.WriteStream(aFileStream);
+        rStream.WriteCharPtr("</reqif-xhtml:html>\n");
+        rStream.Seek(0);
+    }
+
 private:
     bool mustCalcLayoutOf(const char* filename) override
     {
@@ -603,11 +617,7 @@ DECLARE_HTMLEXPORT_TEST(testTransparentImage, 
"transparent-image.odt")
 DECLARE_HTMLEXPORT_TEST(testTransparentImageReqIf, "transparent-image.odt")
 {
     SvMemoryStream aStream;
-    aStream.WriteCharPtr("<reqif-xhtml:html 
xmlns:reqif-xhtml=\"http://www.w3.org/1999/xhtml\";>\n");
-    SvFileStream aFileStream(maTempFile.GetURL(), StreamMode::READ);
-    aStream.WriteStream(aFileStream);
-    aStream.WriteCharPtr("</reqif-xhtml:html>\n");
-    aStream.Seek(0);
+    wrapFragment(aStream);
     xmlDocPtr pDoc = parseXmlStream(&aStream);
     CPPUNIT_ASSERT(pDoc);
 
@@ -620,6 +630,22 @@ DECLARE_HTMLEXPORT_TEST(testTransparentImageReqIf, 
"transparent-image.odt")
     CPPUNIT_ASSERT_MESSAGE(aMessage.toUtf8().getStr(), 
aSource.endsWith(".png"));
 }
 
+DECLARE_HTMLEXPORT_TEST(testOleNodataReqIf, "reqif-ole-nodata.odt")
+{
+    // This failed, io::IOException was thrown during the filter() call.
+    SvMemoryStream aStream;
+    wrapFragment(aStream);
+    xmlDocPtr pDoc = parseXmlStream(&aStream);
+    CPPUNIT_ASSERT(pDoc);
+
+    // Make sure the native <object> element has the required data attribute.
+    OUString aSource = getXPath(
+        pDoc,
+        
"/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object/reqif-xhtml:object",
+        "data");
+    CPPUNIT_ASSERT(!aSource.isEmpty());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlplug.cxx 
b/sw/source/filter/html/htmlplug.cxx
index d054fd393f65..cea1a75cacd0 100644
--- a/sw/source/filter/html/htmlplug.cxx
+++ b/sw/source/filter/html/htmlplug.cxx
@@ -63,6 +63,7 @@
 #include <com/sun/star/frame/XStorable.hpp>
 #include <com/sun/star/embed/ElementModes.hpp>
 #include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/io/IOException.hpp>
 #include <com/sun/star/embed/XEmbedPersist2.hpp>
 
 #include <comphelper/embeddedobjectcontainer.hxx>
@@ -74,6 +75,7 @@
 #include <comphelper/propertysequence.hxx>
 #include <filter/msfilter/msoleexp.hxx>
 #include <comphelper/fileurl.hxx>
+#include <osl/file.hxx>
 
 using namespace com::sun::star;
 
@@ -130,6 +132,33 @@ const HtmlFrmOpts HTML_FRMOPTS_OLE_CSS1       =
     HtmlFrmOpts::SAlign |
     HtmlFrmOpts::SSpace;
 
+namespace
+{
+/**
+ * Calculates a filename for an image, provided the HTML file name, the image
+ * itself and a wanted extension.
+ */
+OUString lcl_CalculateFileName(const OUString* pOrigFileName, const Graphic& 
rGraphic,
+                               const OUString& rExtension)
+{
+    OUString aFileName;
+
+    if (pOrigFileName)
+        aFileName = *pOrigFileName;
+    INetURLObject aURL(aFileName);
+    OUString aName(aURL.getBase());
+    aName += "_";
+    aName += aURL.getExtension();
+    aName += "_";
+    aName += OUString::number(rGraphic.GetChecksum(), 16);
+    aURL.setBase(aName);
+    aURL.setExtension(rExtension);
+    aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+
+    return aFileName;
+}
+}
+
 void SwHTMLParser::SetFixSize( const Size& rPixSize,
                                const Size& rTwipDfltSize,
                                bool bPrcWidth, bool bPrcHeight,
@@ -1465,18 +1494,7 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, 
const SwFrameFormat& rFrame
 
         // Calculate the file name, which is meant to be the same as the
         // replacement image, just with a .ole extension.
-        OUString aFileName;
-        if (rHTMLWrt.GetOrigFileName())
-            aFileName = *rHTMLWrt.GetOrigFileName();
-        INetURLObject aURL(aFileName);
-        OUString aName(aURL.getBase());
-        aName += "_";
-        aName += aURL.getExtension();
-        aName += "_";
-        aName += OUString::number(aGraphic.GetChecksum(), 16);
-        aURL.setBase(aName);
-        aURL.setExtension("ole");
-        aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+        OUString aFileName = lcl_CalculateFileName(rHTMLWrt.GetOrigFileName(), 
aGraphic, "ole");
 
         // Write the data.
         SwOLEObj& rOLEObj = pOLENd->GetOLEObj();
@@ -1527,11 +1545,22 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, 
const SwFrameFormat& rFrame
             // Otherwise the native data is just a grab-bag: 
ODummyEmbeddedObject.
             OUString aStreamName = rOLEObj.GetCurrentPersistName();
             uno::Reference<embed::XStorage> xStorage = pDocSh->GetStorage();
-            uno::Reference<io::XStream> xInStream
-                = xStorage->openStreamElement(aStreamName, 
embed::ElementModes::READ);
-            uno::Reference<io::XStream> xOutStream(new 
utl::OStreamWrapper(aOutStream));
-            
comphelper::OStorageHelper::CopyInputToOutput(xInStream->getInputStream(),
-                                                          
xOutStream->getOutputStream());
+            uno::Reference<io::XStream> xInStream;
+            try
+            {
+                // Even the native data may be missing.
+                xInStream = xStorage->openStreamElement(aStreamName, 
embed::ElementModes::READ);
+            } catch (const uno::Exception& rException)
+            {
+                SAL_WARN("sw.html", "OutHTML_FrameFormatOLENodeGrf: failed to 
open stream element: " << rException);
+            }
+            if (xInStream.is())
+            {
+                uno::Reference<io::XStream> xOutStream(new 
utl::OStreamWrapper(aOutStream));
+                
comphelper::OStorageHelper::CopyInputToOutput(xInStream->getInputStream(),
+                                                              
xOutStream->getOutputStream());
+            }
+
             uno::Reference<beans::XPropertySet> xOutStreamProps(xInStream, 
uno::UNO_QUERY);
             if (xOutStreamProps.is())
                 xOutStreamProps->getPropertyValue("MediaType") >>= aFileType;
@@ -1566,6 +1595,15 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, 
const SwFrameFormat& rFrame
             aFilterName = "PNG";
             nFlags = XOutFlags::NONE;
             aMimeType = "image/png";
+
+            if (aGraphic.GetType() == GraphicType::NONE)
+            {
+                // The OLE Object has no replacement image, write a stub.
+                aGraphicURL = 
lcl_CalculateFileName(rHTMLWrt.GetOrigFileName(), aGraphic, "png");
+                osl::File aFile(aGraphicURL);
+                aFile.open(osl_File_OpenFlag_Create);
+                aFile.close();
+            }
         }
 
         ErrCode nErr = XOutBitmap::WriteGraphic( aGraphic, aGraphicURL,
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to