diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-02-09 16:57:22 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-02-09 17:13:44 +0100 |
commit | 6dc0a4431f48546265d9cab7a8be25131ef18f53 (patch) | |
tree | 1d3495520ebeed04da82df72a4fd27758dddcace /xmlsecurity/source | |
parent | 3c6912429252f6924b0d37e57c3760ebf1cf32b5 (diff) |
xmlsecurity OOXML export: fix prefix and suffix of stream references
In ODF, they're relative to the package root, in OOXML they always start
with a leading slash.
Also, in OOXML the stream URI should have its content type as the
suffix.
Change-Id: Iac570ed15533a23c8a6098f99b716f90e1bac0e0
Diffstat (limited to 'xmlsecurity/source')
-rw-r--r-- | xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 1 | ||||
-rw-r--r-- | xmlsecurity/source/helper/documentsignaturehelper.cxx | 50 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xmlsignaturehelper2.cxx | 10 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecctl.cxx | 9 |
4 files changed, 61 insertions, 9 deletions
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index 30a805efb52c..85da771d1826 100644 --- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx +++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx @@ -474,6 +474,7 @@ IMPL_LINK_NOARG_TYPED(DigitalSignaturesDialog, AddButtonHdl, Button*, void) std::vector< OUString > aElements = DocumentSignatureHelper::CreateElementList( mxStore, meSignatureMode, OOo3_2Document); + DocumentSignatureHelper::AppendContentTypes(mxStore, aElements); sal_Int32 nElements = aElements.size(); for ( sal_Int32 n = 0; n < nElements; n++ ) diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx b/xmlsecurity/source/helper/documentsignaturehelper.cxx index bc361ebb8fd3..b32dca2a901f 100644 --- a/xmlsecurity/source/helper/documentsignaturehelper.cxx +++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx @@ -20,6 +20,8 @@ #include <xmlsecurity/documentsignaturehelper.hxx> +#include <algorithm> + #include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/lang/DisposedException.hpp> @@ -27,8 +29,11 @@ #include <com/sun/star/embed/StorageFormats.hpp> #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/StringPair.hpp> #include <comphelper/documentconstants.hxx> +#include <comphelper/ofopxmlhelper.hxx> +#include <comphelper/processfactory.hxx> #include <tools/debug.hxx> #include <osl/diagnose.h> #include <rtl/uri.hxx> @@ -292,6 +297,51 @@ DocumentSignatureHelper::CreateElementList( return aElements; } +void DocumentSignatureHelper::AppendContentTypes(const uno::Reference<embed::XStorage>& xStorage, std::vector<OUString>& rElements) +{ + uno::Reference<container::XNameAccess> xNameAccess(xStorage, uno::UNO_QUERY); + if (!xNameAccess.is() || !xNameAccess->hasByName("[Content_Types].xml")) + // ODF + return; + + sal_Int32 nOpenMode = embed::ElementModes::READ; + uno::Reference<io::XInputStream> xRelStream(xStorage->openStreamElement("[Content_Types].xml", nOpenMode), uno::UNO_QUERY); + uno::Sequence< uno::Sequence<beans::StringPair> > aContentTypeInfo = comphelper::OFOPXMLHelper::ReadContentTypeSequence(xRelStream, comphelper::getProcessComponentContext()); + if (aContentTypeInfo.getLength() < 2) + { + SAL_WARN("xmlsecurity.helper", "no defaults or overrides in aContentTypeInfo"); + return; + } + uno::Sequence<beans::StringPair>& rDefaults = aContentTypeInfo[0]; + uno::Sequence<beans::StringPair>& rOverrides = aContentTypeInfo[1]; + + for (OUString& rElement : rElements) + { + auto it = std::find_if(rOverrides.begin(), rOverrides.end(), [&](const beans::StringPair& rPair) + { + return rPair.First == "/" + rElement; + }); + + if (it != rOverrides.end()) + { + rElement = "/" + rElement + "?ContentType=" + it->Second; + continue; + } + + it = std::find_if(rDefaults.begin(), rDefaults.end(), [&](const beans::StringPair& rPair) + { + return rElement.endsWith("." + rPair.First); + }); + + if (it != rOverrides.end()) + { + rElement = "/" + rElement + "?ContentType=" + it->Second; + continue; + } + SAL_WARN("xmlsecurity.helper", "found no content type for " << rElement); + } +} + SignatureStreamHelper DocumentSignatureHelper::OpenSignatureStream( const Reference < css::embed::XStorage >& rxStore, sal_Int32 nOpenMode, DocumentSignatureMode eDocSigMode ) { diff --git a/xmlsecurity/source/helper/xmlsignaturehelper2.cxx b/xmlsecurity/source/helper/xmlsignaturehelper2.cxx index 89f6bbc75b65..ebc8a1d8f051 100644 --- a/xmlsecurity/source/helper/xmlsignaturehelper2.cxx +++ b/xmlsecurity/source/helper/xmlsignaturehelper2.cxx @@ -188,6 +188,11 @@ uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno // Ignore leading slash, don't attempt to open a storage with name "". if (aURI.startsWith("/")) aURI = aURI.copy(1); + // Ignore query part of the URI. + sal_Int32 nQueryPos = aURI.indexOf('?'); + if (nQueryPos != -1) + aURI = aURI.copy(0, nQueryPos); + sal_Int32 nSepPos = aURI.indexOf( '/' ); if ( nSepPos == -1 ) @@ -207,11 +212,6 @@ uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno } else { - // Ignore query part of the URI. - sal_Int32 nQueryPos = aURI.indexOf('?'); - if (nQueryPos != -1) - aURI = aURI.copy(0, nQueryPos); - const OUString aStoreName = ::rtl::Uri::decode( aURI.copy( 0, nSepPos ), rtl_UriDecodeStrict, rtl_UriCharClassRelSegment); if (aStoreName.isEmpty() && !aURI.isEmpty()) diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx index b4c3031f5f1f..b45e24b8b725 100644 --- a/xmlsecurity/source/helper/xsecctl.cxx +++ b/xmlsecurity/source/helper/xsecctl.cxx @@ -986,11 +986,12 @@ static bool lcl_isOOXMLBlacklist(const OUString& rStreamName) #endif const std::initializer_list<OUStringLiteral> vBlacklist = { - OUStringLiteral("%5BContent_Types%5D.xml"), - OUStringLiteral("docProps/app.xml"), - OUStringLiteral("docProps/core.xml") + OUStringLiteral("/%5BContent_Types%5D.xml"), + OUStringLiteral("/docProps/app.xml"), + OUStringLiteral("/docProps/core.xml") }; - return std::find(vBlacklist.begin(), vBlacklist.end(), rStreamName) != vBlacklist.end(); + // Just check the prefix, as we don't care about the content type part of the stream name. + return std::find_if(vBlacklist.begin(), vBlacklist.end(), [&](const OUStringLiteral& rLiteral) { return rStreamName.startsWith(rLiteral); }) != vBlacklist.end(); } void XSecController::exportOOXMLSignature(const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler, const SignatureInformation& rInformation) |