[Libreoffice-commits] core.git: Branch 'libreoffice-5-4' - 3 commits - include/oox oox/source sw/qa sw/source writerfilter/inc writerfilter/source
Miklos Vajna
vmiklos at collabora.co.uk
Thu Jun 8 06:04:10 UTC 2017
include/oox/ole/vbaproject.hxx | 4
oox/source/core/filterdetect.cxx | 9 -
oox/source/ole/vbaproject.cxx | 14 ++
sw/qa/extras/rtfimport/data/tdf108123.rtf | 48 ++++++++++
sw/qa/extras/rtfimport/rtfimport.cxx | 10 ++
sw/source/filter/ww8/docxexport.cxx | 104 +++++++++-------------
writerfilter/inc/ooxml/OOXMLDocument.hxx | 3
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 9 +
writerfilter/source/filter/WriterFilter.cxx | 11 +-
writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 75 ---------------
writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 4
writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 23 ++++
writerfilter/source/ooxml/OOXMLStreamImpl.hxx | 3
13 files changed, 159 insertions(+), 158 deletions(-)
New commits:
commit 538186004a1201f4881a64cdf5d905a24f86bfb1
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Wed Jun 7 14:49:38 2017 +0200
Related: tdf#108269 DOCM filter: reuse oox code for VBA data preservation
Which means the DOCM-specific code to roundtrip VBA things (project,
data) can be removed. The oox part has to be extended a bit, as at least
for this DOCM bugdoc there is an XML relation of the binary data, while
existing shared code assumed the full VBA project is just a single OLE
blob.
Reviewed-on: https://gerrit.libreoffice.org/38504
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins <ci at libreoffice.org>
(cherry picked from commit 0129c2cd9dd95355412b194c595f4b986403ba1e)
Conflicts:
writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
Change-Id: I4085e4dba24475e6fd555e5f34fe7ad0f305c57d
Reviewed-on: https://gerrit.libreoffice.org/38545
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
diff --git a/include/oox/ole/vbaproject.hxx b/include/oox/ole/vbaproject.hxx
index 3f0e2b0fccfc..4e6aacf24ad6 100644
--- a/include/oox/ole/vbaproject.hxx
+++ b/include/oox/ole/vbaproject.hxx
@@ -37,6 +37,7 @@ namespace com { namespace sun { namespace star {
namespace script { namespace vba { class XVBAMacroResolver; } }
namespace uno { class XComponentContext; }
namespace uno { class XInterface; }
+ namespace io { class XInputStream; }
} } }
namespace oox {
@@ -130,6 +131,9 @@ public:
bool importVbaProject(
StorageBase& rVbaPrjStrg );
+ /// Imports VBA data for a VBA project, e.g. word/vbaData.xml.
+ void importVbaData(const css::uno::Reference<css::io::XInputStream>& xInputStream);
+
/** Reads vba module related information from the project streams */
void readVbaModules( StorageBase& rVbaPrjStrg );
/** Imports (and creates) vba modules and user forms from the vba project records previously read.
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index ed94ca5a5770..991b3d86a585 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -163,14 +163,7 @@ void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs )
OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType, const OUString& rFileName )
{
- bool bDocm = false;
- OUString aDocmExtension = ".docm";
- if (rFileName.getLength() >= aDocmExtension.getLength())
- {
- OUString aExtension = rFileName.copy(rFileName.getLength() - aDocmExtension.getLength());
- // The file name ends with .docm, ignoring case.
- bDocm = aExtension.equalsIgnoreAsciiCase(aDocmExtension);
- }
+ bool bDocm = rFileName.endsWithIgnoreAsciiCase(".docm");
if( rContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" && !bDocm )
return OUString( "writer_MS_Word_2007" );
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
index e915ba78ea10..c38adc9c3777 100644
--- a/oox/source/ole/vbaproject.cxx
+++ b/oox/source/ole/vbaproject.cxx
@@ -32,6 +32,7 @@
#include <com/sun/star/uno/XComponentContext.hpp>
#include <comphelper/configurationhelper.hxx>
#include <comphelper/string.hxx>
+#include <comphelper/storagehelper.hxx>
#include <osl/diagnose.h>
#include <rtl/tencinfo.h>
#include <rtl/ustrbuf.h>
@@ -49,6 +50,7 @@
namespace oox {
namespace ole {
+using namespace ::com::sun::star;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::embed;
@@ -182,6 +184,18 @@ void VbaProject::importVbaProject( StorageBase& rVbaPrjStrg, const GraphicHelper
}
}
+void VbaProject::importVbaData(const uno::Reference<io::XInputStream>& xInputStream)
+{
+ uno::Reference<document::XStorageBasedDocument> xStorageBasedDoc(mxDocModel, uno::UNO_QUERY);
+ uno::Reference<embed::XStorage> xDocStorage(xStorageBasedDoc->getDocumentStorage(), uno::UNO_QUERY);
+ {
+ const sal_Int32 nOpenMode = ElementModes::SEEKABLE | ElementModes::WRITE | ElementModes::TRUNCATE;
+ uno::Reference<io::XOutputStream> xDocStream(xDocStorage->openStreamElement("_MS_VBA_Macros_XML", nOpenMode), uno::UNO_QUERY);
+ comphelper::OStorageHelper::CopyInputToOutput(xInputStream, xDocStream);
+ }
+ uno::Reference<embed::XTransactedObject>(xDocStorage, uno::UNO_QUERY)->commit();
+}
+
void VbaProject::registerMacroAttacher( const VbaMacroAttacherRef& rxAttacher )
{
OSL_ENSURE( rxAttacher.get(), "VbaProject::registerMacroAttacher - unexpected empty reference" );
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index ae4c27a9aa84..b765a99b7f8d 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1287,51 +1287,30 @@ void DocxExport::WriteVBA()
m_pFilter->addRelation(m_pDocumentFS->getOutputStream(), "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "vbaProject.bin");
}
- uno::Reference<beans::XPropertySet> xPropertySet(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
- if (!xPropertySet.is())
+ OUString aDataName("_MS_VBA_Macros_XML");
+ if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aDataName))
return;
- uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
- if (!xPropertySetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG))
- return;
-
- uno::Sequence<beans::PropertyValue> aGrabBag;
- xPropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBag;
- uno::Sequence<beans::PropertyValue> aVBA;
- for (const auto& rProperty : aGrabBag)
+ uno::Reference<io::XStream> xDataStream(xDocumentStorage->openStreamElement(aDataName, nOpenMode), uno::UNO_QUERY);
+ if (xDataStream.is())
{
- if (rProperty.Name == "OOXVBA")
- rProperty.Value >>= aVBA;
- }
- if (!aVBA.hasElements())
- return;
+ // Then the data stream, which wants to work with an already set
+ // xProjectStream.
+ std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xDataStream));
- for (const auto& rProperty : aVBA)
- {
- if (rProperty.Name == "DataStream")
- {
- // Then the data stream, which wants to work with an already set
- // xProjectStream.
- uno::Reference<io::XStream> xInputStream;
- rProperty.Value >>= xInputStream;
- if (!xInputStream.is())
- return;
- std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xInputStream));
-
- uno::Reference<io::XStream> xOutputStream(GetFilter().openFragmentStream("word/vbaData.xml", "application/vnd.ms-word.vbaData+xml"), uno::UNO_QUERY);
- if (!xOutputStream.is())
- return;
- std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
-
- // Write the stream.
- pOut->WriteStream(*pIn);
-
- // Write the relationship.
- if (!xProjectStream.is())
- return;
-
- m_pFilter->addRelation(xProjectStream, "http://schemas.microsoft.com/office/2006/relationships/wordVbaData", "vbaData.xml");
- }
+ uno::Reference<io::XStream> xOutputStream(GetFilter().openFragmentStream("word/vbaData.xml", "application/vnd.ms-word.vbaData+xml"), uno::UNO_QUERY);
+ if (!xOutputStream.is())
+ return;
+ std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
+
+ // Write the stream.
+ pOut->WriteStream(*pIn);
+
+ // Write the relationship.
+ if (!xProjectStream.is())
+ return;
+
+ m_pFilter->addRelation(xProjectStream, "http://schemas.microsoft.com/office/2006/relationships/wordVbaData", "vbaData.xml");
}
}
diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx
index 009aeba949cc..c7241f946311 100644
--- a/writerfilter/inc/ooxml/OOXMLDocument.hxx
+++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx
@@ -75,7 +75,7 @@ class OOXMLStream
{
public:
enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, WEBSETTINGS, FONTTABLE, NUMBERING,
- FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, FOOTER, HEADER };
+ FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, FOOTER, HEADER, VBADATA };
typedef std::shared_ptr<OOXMLStream> Pointer_t;
virtual ~OOXMLStream() {}
@@ -229,7 +229,6 @@ public:
virtual css::uno::Sequence<css::uno::Reference<css::xml::dom::XDocument> > getActiveXDomList( ) = 0;
virtual css::uno::Sequence<css::uno::Reference<css::io::XInputStream> > getActiveXBinList() = 0;
virtual css::uno::Sequence<css::beans::PropertyValue > getEmbeddingsList() = 0;
- virtual css::uno::Sequence<css::beans::PropertyValue > getVBA() = 0;
};
diff --git a/writerfilter/source/filter/WriterFilter.cxx b/writerfilter/source/filter/WriterFilter.cxx
index 55c70e11eabc..df23ef38bb0c 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -236,9 +236,6 @@ sal_Bool WriterFilter::filter(const uno::Sequence< beans::PropertyValue >& aDesc
// Adding the saved embedding document to document's grab bag
aGrabBagProperties["OOXEmbeddings"] <<= pDocument->getEmbeddingsList();
- if (pDocument->getVBA().hasElements())
- aGrabBagProperties["OOXVBA"] <<= pDocument->getVBA();
-
putPropertiesToDocumentGrabBag(aGrabBagProperties);
writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream(pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT));
@@ -257,6 +254,14 @@ sal_Bool WriterFilter::filter(const uno::Sequence< beans::PropertyValue >& aDesc
oox::GraphicHelper gHelper(m_xContext, xFrame, xVbaPrjStrg);
aVbaProject.importVbaProject(*xVbaPrjStrg, gHelper);
+
+ writerfilter::ooxml::OOXMLStream::Pointer_t pVBADataStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream(pDocStream, writerfilter::ooxml::OOXMLStream::VBADATA));
+ if (pVBADataStream)
+ {
+ uno::Reference<io::XInputStream> xDataStream = pVBADataStream->getDocumentStream();
+ if (xDataStream.is())
+ aVbaProject.importVbaData(xDataStream);
+ }
}
pStream.reset();
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index 3c3aa8822bec..089c0e2a8f26 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -39,7 +39,6 @@
#include <svx/dialogs.hrc>
#include <comphelper/sequence.hxx>
#include <unotools/mediadescriptor.hxx>
-#include <comphelper/propertysequence.hxx>
#include <iostream>
#include "sfx2/objsh.hxx"
@@ -497,9 +496,6 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
resolveActiveXStream(rStream);
- if (!mbIsSubstream)
- preserveVBA();
-
resolveFastSubStream(rStream, OOXMLStream::FONTTABLE);
resolveFastSubStream(rStream, OOXMLStream::STYLES);
resolveFastSubStream(rStream, OOXMLStream::NUMBERING);
@@ -812,71 +808,6 @@ void OOXMLDocumentImpl::resolveEmbeddingsStream(const OOXMLStream::Pointer_t& pS
mxEmbeddingsList = comphelper::containerToSequence(aEmbeddings);
}
-namespace
-{
-/// Returns the target string for rType in xRelationshipAccess.
-OUString getTypeTarget(const uno::Reference<embed::XRelationshipAccess>& xRelationshipAccess, const OUString& rType)
-{
- uno::Sequence< uno::Sequence<beans::StringPair> > aRelations = xRelationshipAccess->getAllRelationships();
- for (const auto& rRelation : aRelations)
- {
- OUString aType;
- OUString aTarget;
- for (const auto& rPair : rRelation)
- {
- if (rPair.First == "Type")
- aType = rPair.Second;
- else if (rPair.First == "Target")
- aTarget = rPair.Second;
- }
-
- if (aType == rType)
- return aTarget;
- }
-
- return OUString();
-}
-}
-
-void OOXMLDocumentImpl::preserveVBA()
-{
- auto pOOXMLStream = dynamic_cast<OOXMLStreamImpl*>(mpStream.get());
- if (!pOOXMLStream)
- return;
-
- uno::Reference<embed::XRelationshipAccess> xRelationshipAccess(pOOXMLStream->accessDocumentStream(), uno::UNO_QUERY);
- if (!xRelationshipAccess.is())
- return;
-
- OUString aVBAStreamName = getTypeTarget(xRelationshipAccess, "http://schemas.microsoft.com/office/2006/relationships/vbaProject");
- if (aVBAStreamName.isEmpty())
- return;
-
- uno::Reference<embed::XHierarchicalStorageAccess> xStorage(pOOXMLStream->getStorage(), uno::UNO_QUERY);
- if (!xStorage.is())
- return;
-
- OUString aPath = pOOXMLStream->getPath();
- uno::Reference<io::XStream> xStream(xStorage->openStreamElementByHierarchicalName(aPath + aVBAStreamName, embed::ElementModes::SEEKABLEREAD), uno::UNO_QUERY);
- if (!xStream.is())
- return;
-
- xRelationshipAccess.set(xStream, uno::UNO_QUERY);
- uno::Reference<io::XStream> xDataStream;
- if (xRelationshipAccess.is())
- {
- // Check if there is a vbaData.xml for the vbaProject.bin.
- OUString aVBAData = getTypeTarget(xRelationshipAccess, "http://schemas.microsoft.com/office/2006/relationships/wordVbaData");
- if (!aVBAData.isEmpty())
- xDataStream.set(xStorage->openStreamElementByHierarchicalName(aPath + aVBAData, embed::ElementModes::SEEKABLEREAD), uno::UNO_QUERY);
- }
-
- maVBA = comphelper::InitPropertySequence(
- {
- {"DataStream", uno::makeAny(xDataStream)}
- });
-}
-
void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
{
// Resolving all ActiveX[n].xml files from ActiveX folder.
@@ -1016,11 +947,6 @@ uno::Sequence<beans::PropertyValue > OOXMLDocumentImpl::getEmbeddingsList( )
return mxEmbeddingsList;
}
-uno::Sequence<beans::PropertyValue> OOXMLDocumentImpl::getVBA()
-{
- return maVBA;
-}
-
OOXMLDocument *
OOXMLDocumentFactory::createDocument
(const OOXMLStream::Pointer_t& pStream,
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
index c4245cae7b02..43bdeb651d78 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
@@ -53,8 +53,6 @@ class OOXMLDocumentImpl : public OOXMLDocument
css::uno::Reference<css::io::XInputStream> mxActiveXBin;
css::uno::Reference<css::io::XInputStream> mxEmbeddings;
css::uno::Sequence < css::beans::PropertyValue > mxEmbeddingsList;
- /// List of VBA-related streams.
- css::uno::Sequence<css::beans::PropertyValue> maVBA;
bool mbIsSubstream;
bool mbSkipImages;
/// How many paragraphs equal to 1 percent?
@@ -93,7 +91,6 @@ protected:
void resolveActiveXStream(Stream & rStream);
void resolveGlossaryStream(Stream & rStream);
void resolveEmbeddingsStream(const OOXMLStream::Pointer_t& pStream);
- void preserveVBA();
public:
OOXMLDocumentImpl(OOXMLStream::Pointer_t const & pStream, const css::uno::Reference<css::task::XStatusIndicator>& xStatusIndicator, bool bSkipImages, const css::uno::Sequence<css::beans::PropertyValue>& rDescriptor);
virtual ~OOXMLDocumentImpl() override;
@@ -139,7 +136,6 @@ public:
virtual css::uno::Reference<css::xml::dom::XDocument> getGlossaryDocDom() override;
virtual css::uno::Sequence<css::uno::Sequence< css::uno::Any> > getGlossaryDomList() override;
virtual css::uno::Sequence<css::beans::PropertyValue > getEmbeddingsList() override;
- virtual css::uno::Sequence<css::beans::PropertyValue> getVBA() override;
void incrementProgress();
bool IsSkipImages() { return mbSkipImages; };
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
index 9530654dcf3c..ddb89f17b528 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
@@ -172,6 +172,7 @@ bool OOXMLStreamImpl::lcl_getTarget(const uno::Reference<embed::XRelationshipAcc
static const char sHeaderTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/header";
static const char sOleObjectTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/oleObject";
static const char sVBAProjectType[] = "http://schemas.microsoft.com/office/2006/relationships/vbaProject";
+ static const char sVBADataType[] = "http://schemas.microsoft.com/office/2006/relationships/wordVbaData";
OUString sStreamType;
OUString sStreamTypeStrict;
@@ -182,6 +183,10 @@ bool OOXMLStreamImpl::lcl_getTarget(const uno::Reference<embed::XRelationshipAcc
sStreamType = sVBAProjectType;
sStreamTypeStrict = sVBAProjectType;
break;
+ case VBADATA:
+ sStreamType = sVBADataType;
+ sStreamTypeStrict = sVBADataType;
+ break;
case DOCUMENT:
sStreamType = sDocumentType;
sStreamTypeStrict = sDocumentTypeStrict;
@@ -416,8 +421,22 @@ OOXMLDocumentFactory::createStream
(const OOXMLStream::Pointer_t& pStream, OOXMLStream::StreamType_t nStreamType)
{
OOXMLStream::Pointer_t pRet;
- if (OOXMLStreamImpl* pImpl = dynamic_cast<OOXMLStreamImpl *>(pStream.get()))
- pRet.reset(new OOXMLStreamImpl(*pImpl, nStreamType));
+
+ if (nStreamType != OOXMLStream::VBADATA)
+ {
+ if (OOXMLStreamImpl* pImpl = dynamic_cast<OOXMLStreamImpl *>(pStream.get()))
+ pRet.reset(new OOXMLStreamImpl(*pImpl, nStreamType));
+ }
+ else
+ {
+ // VBADATA is not a relation of the document, but of the VBAPROJECT stream.
+ if (OOXMLStreamImpl* pImpl = dynamic_cast<OOXMLStreamImpl *>(pStream.get()))
+ {
+ std::unique_ptr<OOXMLStreamImpl> pProject(new OOXMLStreamImpl(*pImpl, OOXMLStream::VBAPROJECT));
+ pRet.reset(new OOXMLStreamImpl(*pProject, OOXMLStream::VBADATA));
+ }
+ }
+
return pRet;
}
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
index cb0276d84649..aff8189b7396 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx
@@ -80,9 +80,6 @@ public:
// Giving access to mxDocumentStream. It is needed by resolving custom xml to get list of customxml's used in document.
const css::uno::Reference<css::io::XStream>& accessDocumentStream() { return mxDocumentStream;}
-
- const css::uno::Reference<css::embed::XStorage>& getStorage() { return mxStorage; }
- const OUString& getPath() { return msPath; }
};
}}
#endif // INCLUDED_WRITERFILTER_SOURCE_OOXML_OOXMLSTREAMIMPL_HXX
commit 9af01c56237b716c7f3bfe4664fd1ca1cd87edde
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Wed Jun 7 12:27:23 2017 +0200
Related: tdf#108269 DOCM filter: reuse oox code for VBA preservation
With this, the project stream import is shared between DOCM and XLSM.
Change-Id: I8fbffefc5acf28adea4875fa6bc4148a99b5ebef
Reviewed-on: https://gerrit.libreoffice.org/38495
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins <ci at libreoffice.org>
(cherry picked from commit e4adb8d9e77bab353dda26375e11a6b7a456368f)
Reviewed-on: https://gerrit.libreoffice.org/38544
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 25d30ef02d1e..ae4c27a9aa84 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -24,6 +24,7 @@
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <com/sun/star/frame/XModel.hpp>
@@ -1256,6 +1257,36 @@ void DocxExport::WriteActiveX()
void DocxExport::WriteVBA()
{
+ uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+ if (!xStorageBasedDocument.is())
+ return;
+
+ uno::Reference<embed::XStorage> xDocumentStorage(xStorageBasedDocument->getDocumentStorage(), uno::UNO_QUERY);
+ OUString aMacrosName("_MS_VBA_Macros");
+ if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aMacrosName))
+ return;
+
+ const sal_Int32 nOpenMode = embed::ElementModes::READ;
+ uno::Reference<io::XStream> xMacrosStream(xDocumentStorage->openStreamElement(aMacrosName, nOpenMode), uno::UNO_QUERY);
+ uno::Reference<io::XOutputStream> xProjectStream;
+ if (xMacrosStream.is())
+ {
+ // First handle the the project stream, this sets xProjectStream.
+ std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xMacrosStream));
+
+ xProjectStream = GetFilter().openFragmentStream("word/vbaProject.bin", "application/vnd.ms-office.vbaProject");
+ uno::Reference<io::XStream> xOutputStream(xProjectStream, uno::UNO_QUERY);
+ if (!xOutputStream.is())
+ return;
+ std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
+
+ // Write the stream.
+ pOut->WriteStream(*pIn);
+
+ // Write the relationship.
+ m_pFilter->addRelation(m_pDocumentFS->getOutputStream(), "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "vbaProject.bin");
+ }
+
uno::Reference<beans::XPropertySet> xPropertySet(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
if (!xPropertySet.is())
return;
@@ -1275,31 +1306,9 @@ void DocxExport::WriteVBA()
if (!aVBA.hasElements())
return;
- uno::Reference<io::XOutputStream> xProjectStream;
for (const auto& rProperty : aVBA)
{
- if (rProperty.Name == "ProjectStream")
- {
- // First check for the project stream, this sets xProjectStream.
- uno::Reference<io::XStream> xInputStream;
- rProperty.Value >>= xInputStream;
- if (!xInputStream.is())
- return;
- std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xInputStream));
-
- xProjectStream = GetFilter().openFragmentStream("word/vbaProject.bin", "application/vnd.ms-office.vbaProject");
- uno::Reference<io::XStream> xOutputStream(xProjectStream, uno::UNO_QUERY);
- if (!xOutputStream.is())
- return;
- std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(xOutputStream));
-
- // Write the stream.
- pOut->WriteStream(*pIn);
-
- // Write the relationship.
- m_pFilter->addRelation(m_pDocumentFS->getOutputStream(), "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "vbaProject.bin");
- }
- else if (rProperty.Name == "DataStream")
+ if (rProperty.Name == "DataStream")
{
// Then the data stream, which wants to work with an already set
// xProjectStream.
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index 550820be018e..3c3aa8822bec 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -873,7 +873,6 @@ void OOXMLDocumentImpl::preserveVBA()
maVBA = comphelper::InitPropertySequence(
{
- {"ProjectStream", uno::makeAny(xStream)},
{"DataStream", uno::makeAny(xDataStream)}
});
}
commit d51becdd4f469922581924e0ae4c91df2b06beda
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Wed Jun 7 09:44:40 2017 +0200
tdf#108123 RTF paste: fix asymmetric shape <-> table manager stack
Make sure that even if the text append stack is empty (and we return
early) the table manager push/pop operations are in sync with the shape
start/end, otherwise we'll have an empty table manager stack.
That is a problem as
writerfilter::dmapper::DomainMapper_Impl::getTableManager() assumes that
it always has at least one element.
Change-Id: I92b3381e820bc8eaeb351532a6ce8909490c0f30
Reviewed-on: https://gerrit.libreoffice.org/38490
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins <ci at libreoffice.org>
(cherry picked from commit f5375d5539897bff0aef82df92b7d485b8839004)
Reviewed-on: https://gerrit.libreoffice.org/38543
diff --git a/sw/qa/extras/rtfimport/data/tdf108123.rtf b/sw/qa/extras/rtfimport/data/tdf108123.rtf
new file mode 100644
index 000000000000..d4e51c347e84
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/tdf108123.rtf
@@ -0,0 +1,48 @@
+{\rtf1\ansi\deff4\adeflang1025
+\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720\deftab720
+\formprot\formshade
+\paperh15840\paperw12240\margl2880\margr2160\margt720\margb720\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\titlepg\titlepg
+{\headerf\pard\plain }
+{\footerf\pard\plain }
+{\dbch\af30\rtlch \ltrch\loch\loch\f5\hich\af5
+DL and HIPAA}
+\par \sect\sectd\sectunlocked1\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1350\headery720\margbsxn1584\footery720\pgnstarts1\pgnrestart\pgndec\sbkpage\headery720
+\footery720
+\pard\plain \s163\sl-280\slmult0\qj\keep\widctlpar\sb480\sa0\keepn\ltrpar\scaps0\caps0\cf23\b\kerning0\dbch\af19\dbch\af19\afs28\ab\loch\f11\fs28
+{\cf20\dbch\af30\rtlch \ltrch\loch\loch\f5\hich\af5
+Table of Contents}
+\par \pard\plain \s3\sl-280\slmult0\ql\widctlpar\sb240\sa20\keepn\ltrpar\cf20\i\b\loch\f6\hich\af6\qj
+{
+\dbch\af30\rtlch \ltrch\loch\loch\f5\hich\af5
+1.1 Complete Core Security Training}
+\par
+{\shp
+{\*\shpinst\shpwr2\shpwrk3\shpbypara\shpbyignore\shptop178\shpbottom1934\shpbxcolumn\shpbxignore\shpleft5543\shpright9344
+{\sp
+{\sn dxWrapDistLeft}
+{\sv 114300}
+}
+{\sp
+{\sn dxWrapDistRight}
+{\sv 114300}
+}
+{\shptxt\s170\ql\widctlpar\ltrpar\hyphpar0\afs22\cf0\dbch\af26\langfe1033\dbch\af26\alang1025\loch\f7\hich\af7\fs22\lang1033
+{\i\b\dbch\af30\afs16\rtlch \ltrch\loch\fs16\loch\f5\hich\af5
+Aligns with HIPAA Security Rule:}
+\par \s170\ql\widctlpar\ltrpar\hyphpar0\afs22\cf0\dbch\af26\langfe1033\dbch\af26\alang1025\loch\f7\hich\af7\fs22\lang1033\rtlch \ltrch\loch
+\pard}
+}
+}
+\pard\plain \s3\sl-280\slmult0\ql\widctlpar\sb240\sa20\keepn\ltrpar\cf20\i\b\loch\f6\hich\af6\qj
+{
+{\*\bkmkstart _Toc261331228}
+{\*\bkmkstart _Toc276629053}
+\dbch\af30\rtlch \ltrch\loch\loch\f5\hich\af5
+2.2 Create Quality Gates and Bug Bars}
+{
+{\*\bkmkend _Toc261331228}
+{\*\bkmkend _Toc276629053}
+\dbch\af30\rtlch \ltrch\loch\loch\f5\hich\af5
+ }
+\par
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 90fe265d8238..03dbbcfb024f 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -885,6 +885,16 @@ DECLARE_RTFIMPORT_TEST(testFdo61193, "hello.rtf")
paste("fdo61193.rtf", xEnd);
}
+DECLARE_RTFIMPORT_TEST(testTdf108123, "hello.rtf")
+{
+ // This crashed, the shape push/pop and table manager stack went out of
+ // sync -> we tried to de-reference an empty stack.
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xText(xTextDocument->getText(), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xEnd = xText->getEnd();
+ paste("tdf108123.rtf", xEnd);
+}
+
DECLARE_RTFIMPORT_TEST(testShptxtPard, "shptxt-pard.rtf")
{
// The problem was that \pard inside \shptxt caused loss of shape text
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index fc076998fa9b..0b29a1a5a523 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1924,13 +1924,16 @@ uno::Reference<drawing::XShape> DomainMapper_Impl::PopPendingShape()
void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape > & xShape )
{
+ // Append these early, so the context and the table manager stack will be
+ // in sync, even if the text append stack is empty.
+ appendTableManager();
+ appendTableHandler();
+ getTableManager().startLevel();
+
if (m_aTextAppendStack.empty())
return;
uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
- appendTableManager( );
- appendTableHandler( );
- getTableManager().startLevel();
try
{
uno::Reference< lang::XServiceInfo > xSInfo( xShape, uno::UNO_QUERY_THROW );
More information about the Libreoffice-commits
mailing list