[Libreoffice-commits] core.git: sw/source

Vasily Melenchuk (via logerrit) logerrit at kemper.freedesktop.org
Mon May 25 08:06:15 UTC 2020


 sw/source/filter/ww8/wrtww8.cxx |  105 ++++++++++++++++++++++++++++++++++++++++
 sw/source/filter/ww8/wrtww8.hxx |    1 
 2 files changed, 106 insertions(+)

New commits:
commit c6665a0fc8cdad31160daad65c10894cd3174584
Author:     Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Mon May 25 02:15:42 2020 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon May 25 10:05:33 2020 +0200

    sw: add XPackageEncryption save support for binary doc
    
    This adds save support for API-based MS-CRYPTO algos. If we have
    custom encryption data in media descriptor and corresponding service
    is available it will be used during saving.
    
    Change-Id: I814e4a7f73979ff7a65831b99f77f1a9e85916de
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/84438
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 91d049a42e11..c3fe9c0a36f9 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -23,7 +23,10 @@
 #include <com/sun/star/embed/ElementModes.hpp>
 #include <com/sun/star/embed/XStorage.hpp>
 #include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/packages/XPackageEncryption.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
 #include <unotools/ucbstreamhelper.hxx>
+#include <unotools/streamwrap.hxx>
 #include <algorithm>
 #include <map>
 #include <hintids.hxx>
@@ -87,6 +90,8 @@
 #include "sprmids.hxx"
 
 #include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
 #include "writerhelper.hxx"
 #include "writerwordglue.hxx"
 #include "ww8attributeoutput.hxx"
@@ -3666,6 +3671,106 @@ void WW8Export::PrepareStorage()
 }
 
 ErrCode SwWW8Writer::WriteStorage()
+{
+    tools::SvRef<SotStorage> pOrigStg;
+    uno::Reference< packages::XPackageEncryption > xPackageEncryption;
+    std::shared_ptr<SvStream> pSotStorageStream;
+    uno::Sequence< beans::NamedValue > aEncryptionData;
+    if (mpMedium)
+    {
+        // Check for specific encryption requests
+        const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(mpMedium->GetItemSet(), SID_ENCRYPTIONDATA, false);
+        if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData))
+        {
+            ::comphelper::SequenceAsHashMap aHashData(aEncryptionData);
+            OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString());
+
+            if (sCryptoType.getLength())
+            {
+                uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+                uno::Sequence<uno::Any> aArguments{
+                    uno::makeAny(beans::NamedValue("Binary", uno::makeAny(true))) };
+                xPackageEncryption.set(
+                    xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+                        "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), uno::UNO_QUERY);
+
+                if (xPackageEncryption.is())
+                {
+                    // We have an encryptor
+                    // Create new temporary storage for content
+                    pOrigStg = m_pStg;
+                    pSotStorageStream = std::make_shared<SvMemoryStream>();
+                    m_pStg = new SotStorage(*pSotStorageStream);
+                }
+            }
+        }
+    }
+
+    ErrCode nErrorCode = WriteStorageImpl();
+
+    if (xPackageEncryption.is())
+    {
+        m_pStg->Commit();
+        pSotStorageStream->Seek(0);
+
+        // Encrypt data written into temporary storage
+        xPackageEncryption->setupEncryption(aEncryptionData);
+
+        uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pSotStorageStream.get(), false));
+        uno::Sequence<beans::NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream);
+
+        m_pStg = pOrigStg;
+        for (const beans::NamedValue & aStreamData : std::as_const(aStreams))
+        {
+            // To avoid long paths split and open substorages recursively
+            // Splitting paths manually, since comphelper::string::split is trimming special characters like \0x01, \0x09
+            SotStorage * pStorage = m_pStg.get();
+            OUString sFileName;
+            sal_Int32 idx = 0;
+            do
+            {
+                OUString sPathElem = aStreamData.Name.getToken(0, L'/', idx);
+                if (!sPathElem.isEmpty())
+                {
+                    if (idx < 0)
+                    {
+                        sFileName = sPathElem;
+                    }
+                    else
+                    {
+                        pStorage = pStorage->OpenSotStorage(sPathElem);
+                        if (!pStorage)
+                            break;
+                    }
+                }
+            } while (pStorage && idx >= 0);
+
+            if (!pStorage)
+            {
+                nErrorCode = ERRCODE_IO_GENERAL;
+                break;
+            }
+
+            SotStorageStream* pStream = pStorage->OpenSotStream(sFileName);
+            if (!pStream)
+            {
+                nErrorCode = ERRCODE_IO_GENERAL;
+                break;
+            }
+            uno::Sequence<sal_Int8> aStreamContent;
+            aStreamData.Value >>= aStreamContent;
+            size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength());
+            if (nBytesWritten != static_cast<size_t>(aStreamContent.getLength()))
+            {
+                nErrorCode = ERRCODE_IO_CANTWRITE;
+                break;
+            }
+        }
+    }
+
+    return nErrorCode;
+}
+ErrCode SwWW8Writer::WriteStorageImpl()
 {
     // #i34818# - update layout (if present), for SwWriteTable
     SwViewShell* pViewShell = m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 99063ef12a20..8c66df7a630a 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -983,6 +983,7 @@ public:
 private:
     SwWW8Writer(const SwWW8Writer&) = delete;
     SwWW8Writer& operator=(const SwWW8Writer&) = delete;
+    ErrCode WriteStorageImpl();
 };
 
 /// Exporter of the binary Word file formats.


More information about the Libreoffice-commits mailing list