summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-02-09 16:57:22 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-02-09 17:13:44 +0100
commit6dc0a4431f48546265d9cab7a8be25131ef18f53 (patch)
tree1d3495520ebeed04da82df72a4fd27758dddcace /xmlsecurity
parent3c6912429252f6924b0d37e57c3760ebf1cf32b5 (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')
-rw-r--r--xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx2
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx1
-rw-r--r--xmlsecurity/source/helper/documentsignaturehelper.cxx50
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper2.cxx10
-rw-r--r--xmlsecurity/source/helper/xsecctl.cxx9
5 files changed, 63 insertions, 9 deletions
diff --git a/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx
index 9b423a155b47..9ccbd3aff792 100644
--- a/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx
@@ -92,6 +92,8 @@ public:
static OUString GetDocumentContentSignatureDefaultStreamName();
static OUString GetScriptingContentSignatureDefaultStreamName();
static OUString GetPackageSignatureDefaultStreamName();
+ /// In case the storage is OOXML, prepend a leading '/' and append content type to the element URIs.
+ static void AppendContentTypes(const css::uno::Reference<css::embed::XStorage>& xStorage, std::vector<OUString>& rElements);
};
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)