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

Reply via email to