[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