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 <[email protected]> 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 <[email protected]> Tested-by: Jenkins <[email protected]> (cherry picked from commit 0129c2cd9dd95355412b194c595f4b986403ba1e) Conflicts: writerfilter/source/ooxml/OOXMLDocumentImpl.hxx Change-Id: I4085e4dba24475e6fd555e5f34fe7ad0f305c57d Reviewed-on: https://gerrit.libreoffice.org/38545 Tested-by: Jenkins <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> 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 <[email protected]> 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 <[email protected]> Tested-by: Jenkins <[email protected]> (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 <[email protected]> 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 <[email protected]> Tested-by: Jenkins <[email protected]> (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 ); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
