5f73ed1
From 4a0c3edb16edf53b97bea0a0fa59d44a9cc28ca4 Mon Sep 17 00:00:00 2001
0f39a38
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
0f39a38
Date: Thu, 12 Jan 2017 09:49:36 +0000
0f39a38
Subject: [PATCH] in extremis dump Ole10Native payload and launch system viewer
0f39a38
 on it
0f39a38
0f39a38
so embedded plain text documents/source code/etc in word documents can be viewed
0f39a38
by us under Linux
0f39a38
0f39a38
Change-Id: I19e19619070841fe097c70297adc2e8b96d1c581
0f39a38
---
0f39a38
 embeddedobj/source/msole/oleembed.cxx | 61 ++++++++++++++++++++++++++++++++---
0f39a38
 sfx2/source/view/ipclient.cxx         |  2 +-
0f39a38
 2 files changed, 58 insertions(+), 5 deletions(-)
0f39a38
0f39a38
diff --git a/embeddedobj/source/msole/oleembed.cxx b/embeddedobj/source/msole/oleembed.cxx
5f73ed1
index 801e568..7af1c92 100644
0f39a38
--- a/embeddedobj/source/msole/oleembed.cxx
0f39a38
+++ b/embeddedobj/source/msole/oleembed.cxx
0f39a38
@@ -665,18 +665,25 @@ sal_Int32 SAL_CALL OleEmbeddedObject::getCurrentState()
0f39a38
 namespace
0f39a38
 {
0f39a38
 #ifndef _WIN32
0f39a38
-    bool lcl_CopyStream(const uno::Reference<io::XInputStream>& xIn, const uno::Reference<io::XOutputStream>& xOut)
0f39a38
+    bool lcl_CopyStream(const uno::Reference<io::XInputStream>& xIn, const uno::Reference<io::XOutputStream>& xOut, sal_Int32 nMaxCopy = SAL_MAX_INT32)
0f39a38
     {
0f39a38
+        if (nMaxCopy == 0)
0f39a38
+            return false;
0f39a38
+
0f39a38
         const sal_Int32 nChunkSize = 4096;
0f39a38
         uno::Sequence< sal_Int8 > aData(nChunkSize);
0f39a38
         sal_Int32 nTotalRead = 0;
0f39a38
         sal_Int32 nRead;
0f39a38
         do
0f39a38
         {
0f39a38
-            nRead = xIn->readBytes(aData, nChunkSize);
0f39a38
+            if (nTotalRead + aData.getLength() > nMaxCopy)
0f39a38
+            {
0f39a38
+                aData.realloc(nMaxCopy - nTotalRead);
0f39a38
+            }
0f39a38
+            nRead = xIn->readBytes(aData, aData.getLength());
0f39a38
             nTotalRead += nRead;
0f39a38
             xOut->writeBytes(aData);
0f39a38
-        } while (nRead == nChunkSize);
0f39a38
+        } while (nRead == nChunkSize && nTotalRead <= nMaxCopy);
0f39a38
         return nTotalRead != 0;
0f39a38
     }
0f39a38
 #endif
0f39a38
@@ -716,6 +723,52 @@ namespace
0f39a38
 
0f39a38
         bool bCopied = xCONTENTS.is() && lcl_CopyStream(xCONTENTS->getInputStream(), xStream->getOutputStream());
0f39a38
 
0f39a38
+        if (!bCopied)
0f39a38
+        {
0f39a38
+            uno::Reference< io::XStream > xOle10Native;
0f39a38
+            try
0f39a38
+            {
0f39a38
+                xNameContainer->getByName("\1Ole10Native") >>= xOle10Native;
0f39a38
+            }
0f39a38
+            catch (container::NoSuchElementException const&)
0f39a38
+            {
0f39a38
+                // ignore
0f39a38
+            }
0f39a38
+            if (xOle10Native.is())
0f39a38
+            {
0f39a38
+                const uno::Reference<io::XInputStream> xIn = xOle10Native->getInputStream();
0f39a38
+                xIn->skipBytes(4); //size of the entire stream minus 4 bytes
0f39a38
+                xIn->skipBytes(2); //word that represent the directory type
0f39a38
+                uno::Sequence< sal_Int8 > aData(1);
0f39a38
+                sal_Int32 nRead;
0f39a38
+                do
0f39a38
+                {
0f39a38
+                    nRead = xIn->readBytes(aData, 1);
0f39a38
+                } while (nRead == 1 && aData[0] != 0);  // file name plus extension of the attachment null terminated
0f39a38
+                do
0f39a38
+                {
0f39a38
+                    nRead = xIn->readBytes(aData, 1);
0f39a38
+                } while (nRead == 1 && aData[0] != 0);  // Fully Qualified File name with extension
0f39a38
+                xIn->skipBytes(1); //single byte
0f39a38
+                xIn->skipBytes(1); //single byte
0f39a38
+                xIn->skipBytes(2); //Word that represent the directory type
0f39a38
+                xIn->skipBytes(4); //len of string
0f39a38
+                do
0f39a38
+                {
0f39a38
+                    nRead = xIn->readBytes(aData, 1);
0f39a38
+                } while (nRead == 1 && aData[0] != 0);  // Actual string representing the file path
0f39a38
+                uno::Sequence< sal_Int8 > aLenData(4);
0f39a38
+                xIn->readBytes(aLenData, 4); //len of attachment
5f73ed1
+                sal_uInt32 nLen = static_cast<sal_uInt32>(
5f73ed1
+                                              (aLenData[0] & 0xFF) |
5f73ed1
+                                              ((aLenData[1] & 0xFF) <<  8) |
5f73ed1
+                                              ((aLenData[2] & 0xFF) << 16) |
5f73ed1
+                                              ((aLenData[3] & 0xFF) << 24));
0f39a38
+
0f39a38
+                bCopied = lcl_CopyStream(xIn, xStream->getOutputStream(), nLen);
0f39a38
+            }
0f39a38
+        }
0f39a38
+
0f39a38
         uno::Reference< io::XSeekable > xSeekableStor(xObjectStream, uno::UNO_QUERY);
0f39a38
         if (xSeekableStor.is())
0f39a38
             xSeekableStor->seek(0);
0f39a38
@@ -862,7 +915,7 @@ void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
0f39a38
                 }
0f39a38
             }
0f39a38
 
0f39a38
-            if ( m_aFilterName != "Text" && (!m_pOwnView || !m_pOwnView->Open()) )
0f39a38
+            if (!m_pOwnView || !m_pOwnView->Open())
0f39a38
             {
0f39a38
                 //Make a RO copy and see if the OS can find something to at
0f39a38
                 //least display the content for us
0f39a38
diff --git a/sfx2/source/view/ipclient.cxx b/sfx2/source/view/ipclient.cxx
5f73ed1
index 1f2b56b..484b3a6 100644
0f39a38
--- a/sfx2/source/view/ipclient.cxx
0f39a38
+++ b/sfx2/source/view/ipclient.cxx
5f73ed1
@@ -937,7 +937,7 @@ ErrCode SfxInPlaceClient::DoVerb( long nVerb )
0f39a38
                 }
0f39a38
                 catch ( embed::UnreachableStateException& )
0f39a38
                 {
0f39a38
-                    if ( nVerb == 0 || nVerb == embed::EmbedVerbs::MS_OLEVERB_OPEN )
348ed4e
+                    if (nVerb == embed::EmbedVerbs::MS_OLEVERB_PRIMARY || nVerb == embed::EmbedVerbs::MS_OLEVERB_OPEN || nVerb == embed::EmbedVerbs::MS_OLEVERB_SHOW)
0f39a38
                     {
0f39a38
                         // a workaround for the default verb, usually makes sense for alien objects
0f39a38
                         try
0f39a38
-- 
0f39a38
2.9.3
0f39a38