sw/inc/format.hxx | 1 + sw/inc/ndtxt.hxx | 4 ++-- sw/source/core/attr/format.cxx | 19 +++++++++++++------ sw/source/core/doc/fmtcol.cxx | 1 + sw/source/core/txtnode/ndtxt.cxx | 28 +++++++++++++++++----------- 5 files changed, 34 insertions(+), 19 deletions(-)
New commits: commit 6a064b1967e06e40be40817deff99d00c1a8554f Author: Matt K <matt...@gmail.com> AuthorDate: Sat Feb 3 17:04:19 2024 -0600 Commit: Matt K <matt...@gmail.com> CommitDate: Wed Feb 28 22:08:38 2024 +0100 tdf#139004 Prevent crash when deleting footnote styles The problem was that a pointer was assumed valid, but was not, so now we check the value of the pointer before using it. Works now to delete footnote style. Also, change assert to variable check to ensure the proper method is only called when it is supposed to be, and to prevent a failing assert. We add a new Destr method on SwFormat so that it can be called from the SwTextFormatColl context and thus avoid the assert. Change-Id: Ia4b8029fb89e627cd685b3317606e2b9d60cf248 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162965 Tested-by: Jenkins Reviewed-by: Matt K <matt...@gmail.com> diff --git a/sw/inc/format.hxx b/sw/inc/format.hxx index 91043b1621de..62ef891bc545 100644 --- a/sw/inc/format.hxx +++ b/sw/inc/format.hxx @@ -72,6 +72,7 @@ protected: SwFormat *pDrvdFrame, sal_uInt16 nFormatWhich ); SwFormat( const SwFormat& rFormat ); virtual void SwClientNotify(const SwModify&, const SfxHint&) override; + void Destr(); public: diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index 352dad71c247..eb046bc9151d 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -454,8 +454,8 @@ public: inline SwTextFormatColl *GetTextColl() const; virtual SwFormatColl *ChgFormatColl( SwFormatColl* ) override; - void ChgTextCollUpdateNum( const SwTextFormatColl* pOld, - const SwTextFormatColl* pNew ); + void ChgTextCollUpdateNum(const SwTextFormatColl* pOld, + const SwTextFormatColl* pNew ); /** Copy collection with all auto formats to dest-node. The latter might be in another document! diff --git a/sw/source/core/attr/format.cxx b/sw/source/core/attr/format.cxx index 6f2f076881e9..fb03edef251b 100644 --- a/sw/source/core/attr/format.cxx +++ b/sw/source/core/attr/format.cxx @@ -200,27 +200,34 @@ void SwFormat::CopyAttrs( const SwFormat& rFormat ) delete pChgSet; } -SwFormat::~SwFormat() +void SwFormat::Destr() { // This happens at an ObjectDying message. Thus put all dependent // ones on DerivedFrom. - if(!HasWriterListeners()) + if (!HasWriterListeners()) return; m_bFormatInDTOR = true; - if(!DerivedFrom()) + if (!DerivedFrom()) { SwFormat::ResetFormatAttr(RES_PAGEDESC); - SAL_WARN("sw.core", "~SwFormat: format still has clients on death, but parent format is missing: " << GetName()); + SAL_WARN("sw.core", + "~SwFormat: format still has clients on death, but parent format is missing: " + << GetName()); return; } - SwIterator<SwClient,SwFormat> aIter(*this); - for(SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next()) + SwIterator<SwClient, SwFormat> aIter(*this); + for (SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next()) pClient->CheckRegistrationFormat(*this); assert(!HasWriterListeners()); } +SwFormat::~SwFormat() +{ + Destr(); +} + void SwFormat::SwClientNotify(const SwModify&, const SfxHint& rHint) { if (rHint.GetId() != SfxHintId::SwLegacyModify) diff --git a/sw/source/core/doc/fmtcol.cxx b/sw/source/core/doc/fmtcol.cxx index 4d87241a03ba..02f2cb5bc2fd 100644 --- a/sw/source/core/doc/fmtcol.cxx +++ b/sw/source/core/doc/fmtcol.cxx @@ -124,6 +124,7 @@ SwTextFormatColl::~SwTextFormatColl() pCharFormat->SetLinkedParaFormat(nullptr); } } + Destr(); } void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rHint) { diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 0a54b140b68c..dc2625d33c54 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -1663,13 +1663,14 @@ void SwTextNode::Update( } } -void SwTextNode::ChgTextCollUpdateNum( const SwTextFormatColl *pOldColl, - const SwTextFormatColl *pNewColl) +void SwTextNode::ChgTextCollUpdateNum(const SwTextFormatColl* pOldColl, + const SwTextFormatColl* pNewColl) { SwDoc& rDoc = GetDoc(); // query the OutlineLevel and if it changed, notify the Nodes-Array! - const int nOldLevel = pOldColl && pOldColl->IsAssignedToListLevelOfOutlineStyle() ? - pOldColl->GetAssignedOutlineStyleLevel() : MAXLEVEL; + const int nOldLevel = pOldColl && pOldColl->IsAssignedToListLevelOfOutlineStyle() + ? pOldColl->GetAssignedOutlineStyleLevel() + : MAXLEVEL; const int nNewLevel = pNewColl && pNewColl->IsAssignedToListLevelOfOutlineStyle() ? pNewColl->GetAssignedOutlineStyleLevel() : MAXLEVEL; @@ -3017,8 +3018,9 @@ bool SwTextNode::HasMarkedLabel() const if ( IsInList() ) { - bResult = - GetDoc().getIDocumentListsAccess().getListByName( GetListId() )->IsListLevelMarked( GetActualListLevel() ); + SwList* pList = GetDoc().getIDocumentListsAccess().getListByName(GetListId()); + if (pList) + bResult = pList->IsListLevelMarked(GetActualListLevel()); } return bResult; @@ -5490,11 +5492,15 @@ void SwTextNode::TriggerNodeUpdate(const sw::LegacyModifyHint& rHint) && GetRegisteredIn() == static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat && GetNodes().IsDocNodes() ) { - assert(dynamic_cast<SwTextFormatColl const*>(static_cast<const SwFormatChg*>(pOldValue)->pChangedFormat)); - assert(dynamic_cast<SwTextFormatColl const*>(static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat)); - ChgTextCollUpdateNum( - static_cast<const SwTextFormatColl*>(static_cast<const SwFormatChg*>(pOldValue)->pChangedFormat), - static_cast<const SwTextFormatColl*>(static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat) ); + assert(dynamic_cast<const SwTextFormatColl*>( + static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat)); + if (const SwTextFormatColl* pTxtFmtColOld = dynamic_cast<const SwTextFormatColl*>( + static_cast<const SwFormatChg*>(pOldValue)->pChangedFormat)) + { + ChgTextCollUpdateNum( + pTxtFmtColOld, static_cast<const SwTextFormatColl*>( + static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat)); + } } // reset fill information