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
This commit is contained in:
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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++ )
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user