sw/inc/ndole.hxx | 15 ++++++++ sw/source/core/doc/DocumentContentOperationsManager.cxx | 6 +++ sw/source/core/doc/DocumentRedlineManager.cxx | 2 - sw/source/core/ole/ndole.cxx | 14 +++++++ sw/source/filter/basflt/shellio.cxx | 6 +-- writerfilter/source/dmapper/DomainMapper_Impl.cxx | 29 +++++++++------- 6 files changed, 57 insertions(+), 15 deletions(-)
New commits: commit d3c893f7446b5e3ca7fb0f811854c8394735c060 Author: Caolán McNamara <[email protected]> AuthorDate: Thu Jun 23 14:35:35 2022 +0100 Commit: Gabor Kelemen <[email protected]> CommitDate: Fri Mar 3 12:07:57 2023 +0100 crashtesting: assert on loading forum-mso-en-11942.docx with getToken index past end Change-Id: I9bfeb9cacd8ad89de8008d37c88d15350ef84fb3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136340 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 666c60d04e5d..049a644cbef8 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -5107,19 +5107,26 @@ void DomainMapper_Impl::CloseFieldCommand() case FIELD_LASTSAVEDBY : break; case FIELD_MACROBUTTON: { - //extract macro name - sal_Int32 nIndex = sizeof(" MACROBUTTON "); - OUString sMacro = pContext->GetCommand().getToken( 0, ' ', nIndex); if (xFieldProperties.is()) - xFieldProperties->setPropertyValue( - getPropertyName(PROP_MACRO_NAME), uno::makeAny( sMacro )); - - //extract quick help text - if(xFieldProperties.is() && pContext->GetCommand().getLength() > nIndex + 1) { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_HINT), - uno::makeAny( pContext->GetCommand().copy( nIndex ))); + sal_Int32 nIndex = sizeof(" MACROBUTTON "); + OUString sCommand = pContext->GetCommand(); + + //extract macro name + if (sCommand.getLength() >= nIndex) + { + OUString sMacro = sCommand.getToken(0, ' ', nIndex); + xFieldProperties->setPropertyValue( + getPropertyName(PROP_MACRO_NAME), uno::Any( sMacro )); + } + + //extract quick help text + if (sCommand.getLength() > nIndex + 1) + { + xFieldProperties->setPropertyValue( + getPropertyName(PROP_HINT), + uno::Any( sCommand.copy( nIndex ))); + } } } break; commit ee1c77a325e8d18725592372bd402c5f79842012 Author: Caolán McNamara <[email protected]> AuthorDate: Tue Nov 26 16:45:48 2019 +0000 Commit: Gabor Kelemen <[email protected]> CommitDate: Fri Mar 3 08:50:25 2023 +0100 crashtesting: export of fdo50613-3.odt to docx crashes there are multiple objects in the doc and the ole cache hovers at the max size at which it wants to purge excess object. On save to docx, object a's chart model is fetched in order to save it, this triggers activating that object a, so object b is purged from the cache. storeOwn is called on b to save it to the document persist storage. During save of object b to document persist, ChartView::getExplicitValuesForAxis is called, which calls impl_updateView which eventually calls lcl_setDefaultWritingMode. *if* IsCTLFontEnabled is on, then chart digs through its parents objects looking for a chart in order to see what the writing direction is at the insertion point of the chart, or failing that for the page its on) (this also seems dubious as it might be any chart, not the current chart) To see if the object is a chart it calls getPropertyValue("CLSID") which brings the object into the ole cache, another object is purged from the cache, and the object purged is object b (which is in progress of getting purged already) object b is now purged in the inner case, so when control is returned to the outer storeOwn the object properties have been deleted and all is lost disallow a purge within a purge Change-Id: Ia21e794759aa82b6bcf39c638be8b47ac58a9bb3 Reviewed-on: https://gerrit.libreoffice.org/83808 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Caolán McNamara <[email protected]> diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx index 852fffd84e3d..b413d5af187d 100644 --- a/sw/inc/ndole.hxx +++ b/sw/inc/ndole.hxx @@ -168,6 +168,21 @@ inline const SwOLENode *SwNode::GetOLENode() const return SwNodeType::Ole == m_nNodeType ? static_cast<const SwOLENode*>(this) : nullptr; } +namespace sw +{ + class DocumentSettingManager; +} + +class SW_DLLPUBLIC PurgeGuard +{ +private: + ::sw::DocumentSettingManager &m_rManager; + bool m_bOrigPurgeOle; +public: + PurgeGuard(const SwDoc& rDoc); + ~PurgeGuard(); +}; + #endif // _ INCLUDED_SW_INC_NDOLE_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx index 9000d6ef1b9e..ff7233a74a45 100644 --- a/sw/source/core/ole/ndole.cxx +++ b/sw/source/core/ole/ndole.cxx @@ -980,6 +980,18 @@ bool SwOLEObj::UnloadObject() return bRet; } +PurgeGuard::PurgeGuard(const SwDoc& rDoc) + : m_rManager(const_cast<SwDoc&>(rDoc).GetDocumentSettingManager()) + , m_bOrigPurgeOle(m_rManager.get(DocumentSettingId::PURGE_OLE)) +{ + m_rManager.set(DocumentSettingId::PURGE_OLE, false); +} + +PurgeGuard::~PurgeGuard() +{ + m_rManager.set(DocumentSettingId::PURGE_OLE, m_bOrigPurgeOle); +} + bool SwOLEObj::UnloadObject( uno::Reference< embed::XEmbeddedObject > const & xObj, const SwDoc* pDoc, sal_Int64 nAspect ) { if ( !pDoc ) @@ -1006,6 +1018,8 @@ bool SwOLEObj::UnloadObject( uno::Reference< embed::XEmbeddedObject > const & xO { uno::Reference < embed::XEmbedPersist > xPers( xObj, uno::UNO_QUERY ); assert(xPers.is() && "Modified object without persistence in cache!"); + + PurgeGuard aGuard(*pDoc); xPers->storeOwn(); } diff --git a/sw/source/filter/basflt/shellio.cxx b/sw/source/filter/basflt/shellio.cxx index 47657980602f..5c80d7da6fef 100644 --- a/sw/source/filter/basflt/shellio.cxx +++ b/sw/source/filter/basflt/shellio.cxx @@ -58,6 +58,7 @@ #include <poolfmt.hxx> #include <fltini.hxx> #include <docsh.hxx> +#include <ndole.hxx> #include <ndtxt.hxx> #include <redline.hxx> #include <swerror.h> @@ -854,8 +855,7 @@ ErrCode SwWriter::Write( WriterRef const & rxWriter, const OUString* pRealFileNa pESh->StartAllAction(); } - const bool bOrigPurgeOle = pOutDoc->getIDocumentSettingAccess().get(DocumentSettingId::PURGE_OLE); - pOutDoc->getIDocumentSettingAccess().set(DocumentSettingId::PURGE_OLE, false); + auto xGuard = std::make_unique<PurgeGuard>(*pOutDoc); ErrCode nError = ERRCODE_NONE; if( pMedium ) @@ -865,7 +865,7 @@ ErrCode SwWriter::Write( WriterRef const & rxWriter, const OUString* pRealFileNa else if( xStg.is() ) nError = rxWriter->Write( *pPam, xStg, pRealFileName ); - pOutDoc->getIDocumentSettingAccess().set(DocumentSettingId::PURGE_OLE, bOrigPurgeOle ); + xGuard.reset(); if( pESh ) { commit 8b1efdc1d7fd9ae86c996d706aa2d419ae8470f5 Author: Michael Stahl <[email protected]> AuthorDate: Fri Jul 15 20:55:35 2022 +0200 Commit: Gabor Kelemen <[email protected]> CommitDate: Thu Mar 2 23:09:57 2023 +0100 tdf#149548 sw: don't rely on binary search in SplitRedline() The problem is that for this bugdoc overlapping redlines are created by writerfilter, and so this one survives the split in SwDoc::TextToTable() when creating a cell on node 146 to 149: $125 = (SwRangeRedline) { <SwPaM> = SwPaM = { point = SwPosition (node 155, offset 156), mark = SwPosition (node 146, offset 0) }, It's not found in GetRedline(), as that relies on the redlines never overlapping, so isn't split at end of 149. Then when copying to the clipboard, all redlines are deleted and this deletes cell start and end nodes, while the cell's SwTableBox is still referenced elsewhere. (reportedly somehow a regression from commit c4cf85766453982f1aa94a7f2cb22af19ed100be) Change-Id: I6466e6777cd83c7625381f7049f30c8a2f487af1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137110 Tested-by: Jenkins Reviewed-by: Michael Stahl <[email protected]> diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index e11c1c6f2c4b..718492ab3f79 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -2325,7 +2325,7 @@ bool DocumentRedlineManager::SplitRedline( const SwPaM& rRange ) SwRedlineTable::size_type n = 0; const SwPosition* pStt = rRange.Start(); const SwPosition* pEnd = rRange.End(); - GetRedline( *pStt, &n ); + //FIXME overlapping problem GetRedline( *pStt, &n ); for ( ; n < mpRedlineTable->size(); ++n) { SwRangeRedline * pRedline = (*mpRedlineTable)[ n ]; commit d9badbf0ec13ae1aadd7abdc8293026359d112fa Author: Michael Stahl <[email protected]> AuthorDate: Wed Nov 24 12:23:10 2021 +0100 Commit: Gabor Kelemen <[email protected]> CommitDate: Thu Mar 2 19:57:43 2023 +0100 tdf#145621 sw: fix crash pasting paragraph with cross-reference mark At last, a case where copying a mark fails for legitimate reasons. (regression from 4bf04dea9afb30a9395e80b07a81d1908937ee8b) Change-Id: I7a318e03c0b0d30e204eadb5012f190edbbba486 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125767 Tested-by: Jenkins Reviewed-by: Michael Stahl <[email protected]> diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 315cf5cdeefa..d90a40b60ea6 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -286,6 +286,12 @@ namespace sw ::sw::mark::InsertMode::CopyText); // Explicitly try to get exactly the same name as in the source // because NavigatorReminders, DdeBookmarks etc. ignore the proposed name + if (pNewMark == nullptr) + { + assert(IDocumentMarkAccess::GetType(*pMark) == IDocumentMarkAccess::MarkType::CROSSREF_NUMITEM_BOOKMARK + || IDocumentMarkAccess::GetType(*pMark) == IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK); + continue; // can't insert duplicate cross reference mark + } pDestDoc->getIDocumentMarkAccess()->renameMark(pNewMark, pMark->GetName()); // copying additional attributes for bookmarks or fieldmarks
