summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorBjoern Michaelsen <bjoern.michaelsen@libreoffice.org>2021-01-03 23:27:49 +0100
committerBjoern Michaelsen <bjoern.michaelsen@libreoffice.org>2021-01-09 03:59:46 +0100
commitd656da9bc4f2df0bb99c65a288847e3fdd43a37c (patch)
tree9a39ad3b93e02af6a5944c8fecc5455d9cdb3b2d /sw
parent3e6c27ac7c42668152b8a636ab875bbf0b9994b2 (diff)
~SwModify: do not silently tolerate clients registered past death
- Make SwFormat/SwContentNode explicitly resetting the page desc. before death instead of SwFormatPageDesc trying to do that on the dying hint: * the dying hints is send _after_ the SwFormat/SwContentNode dtor are completed, so the RTTI magic did not work anyway * simply resetting the attribute in a final dtor and make SwFormatPageDesc just check to never get a dying hint (because it should have been destructed by reset) is a lot less errorprone. Change-Id: I231f1729729491ba7544e5ba93d81192b212e2ae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108648 Tested-by: Jenkins Reviewed-by: Bjoern Michaelsen <bjoern.michaelsen@libreoffice.org>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/ndgrf.hxx2
-rw-r--r--sw/inc/ndole.hxx2
-rw-r--r--sw/inc/ndtxt.hxx6
-rw-r--r--sw/source/core/attr/calbck.cxx12
-rw-r--r--sw/source/core/attr/format.cxx3
-rw-r--r--sw/source/core/crsr/crsrsh.cxx11
-rw-r--r--sw/source/core/graphic/ndgrf.cxx1
-rw-r--r--sw/source/core/layout/atrfrm.cxx32
-rw-r--r--sw/source/core/ole/ndole.cxx1
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx1
10 files changed, 36 insertions, 35 deletions
diff --git a/sw/inc/ndgrf.hxx b/sw/inc/ndgrf.hxx
index 82be71429780..d9fd29e5c2eb 100644
--- a/sw/inc/ndgrf.hxx
+++ b/sw/inc/ndgrf.hxx
@@ -31,7 +31,7 @@ class SwGrfFormatColl;
class SwDoc;
// SwGrfNode
-class SW_DLLPUBLIC SwGrfNode: public SwNoTextNode
+class SW_DLLPUBLIC SwGrfNode final: public SwNoTextNode
{
friend class SwNodes;
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index e54be15a22dd..39060d62501b 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -82,7 +82,7 @@ public:
// SwOLENode
-class SW_DLLPUBLIC SwOLENode: public SwNoTextNode
+class SW_DLLPUBLIC SwOLENode final: public SwNoTextNode
{
friend class SwNodes;
mutable SwOLEObj maOLEObj;
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 7692dc5b6470..f83bab3cebba 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -77,7 +77,7 @@ namespace com::sun::star {
typedef o3tl::sorted_vector< sal_Int32 > SwSoftPageBreakList;
/// SwTextNode is a paragraph in the document model.
-class SW_DLLPUBLIC SwTextNode
+class SW_DLLPUBLIC SwTextNode final
: public SwContentNode
, public ::sfx2::Metadatable
, public sw::FormatDropDefiner
@@ -127,7 +127,7 @@ class SW_DLLPUBLIC SwTextNode
SAL_DLLPRIVATE SwTextNode( const SwNodeIndex &rWhere, SwTextFormatColl *pTextColl,
const SfxItemSet* pAutoAttr = nullptr );
-
+ virtual void SwClientNotify( const SwModify&, const SfxHint& ) override;
/// Copies the attributes at nStart to pDest.
SAL_DLLPRIVATE void CopyAttr( SwTextNode *pDest, const sal_Int32 nStart, const sal_Int32 nOldPos);
@@ -202,8 +202,6 @@ public:
/// End: Data collected during idle time
-protected:
- virtual void SwClientNotify( const SwModify&, const SfxHint& ) override;
public:
using SwContentNode::GetAttr;
diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx
index 6acee52c9231..7450afad6c3f 100644
--- a/sw/source/core/attr/calbck.cxx
+++ b/sw/source/core/attr/calbck.cxx
@@ -163,10 +163,14 @@ SwModify::~SwModify()
SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
NotifyClients( &aDyObject, &aDyObject );
- // remove all clients that have not done themselves
- // mba: possibly a hotfix for forgotten base class calls?!
- while( m_pWriterListeners )
- static_cast<SwClient*>(m_pWriterListeners)->CheckRegistration( &aDyObject );
+ const bool hasListenersOnDeath = m_pWriterListeners;
+ (void)hasListenersOnDeath;
+ while(m_pWriterListeners)
+ {
+ SAL_WARN("sw.core", "lost a client of type: " << typeid(*m_pWriterListeners).name() << " at " << m_pWriterListeners << " still registered on type: " << typeid(*this).name() << " at " << this << ".");
+ static_cast<SwClient*>(m_pWriterListeners)->CheckRegistration(&aDyObject);
+ }
+ assert(!hasListenersOnDeath);
}
void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
diff --git a/sw/source/core/attr/format.cxx b/sw/source/core/attr/format.cxx
index 4b0529d2f253..1f83d913be38 100644
--- a/sw/source/core/attr/format.cxx
+++ b/sw/source/core/attr/format.cxx
@@ -219,9 +219,10 @@ SwFormat::~SwFormat()
return;
m_bFormatInDTOR = true;
-
+
if(!DerivedFrom())
{
+ SwFormat::ResetFormatAttr(RES_PAGEDESC);
SAL_WARN("sw.core", "~SwFormat: format still has clients on death, but parent format is missing: " << GetName());
return;
}
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 1aba8c3ac22f..2b36d8c8c3c9 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -2494,9 +2494,16 @@ void SwCursorShell::SwClientNotify(const SwModify&, const SfxHint& rHint)
// SwTextNode::Insert(SwTextHint*, sal_uInt16); we react here and thus do
// not need to send the expensive RES_FMT_CHG in Insert.
CallChgLnk();
+ switch(nWhich)
+ {
+ case RES_OBJECTDYING:
+ EndListeningAll();
+ break;
+ case RES_GRAPHIC_SWAPIN:
+ if(m_aGrfArrivedLnk.IsSet())
+ m_aGrfArrivedLnk.Call(*this);
+ }
- if(m_aGrfArrivedLnk.IsSet() && RES_GRAPHIC_SWAPIN == nWhich)
- m_aGrfArrivedLnk.Call( *this );
}
/** Does the current cursor create a selection?
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
index b7ab6e94e44a..19db918cc8ff 100644
--- a/sw/source/core/graphic/ndgrf.cxx
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -302,6 +302,7 @@ SwGrfNode::~SwGrfNode()
//#39289# delete frames already here since the Frames' dtor needs the graphic for its StopAnimation
if( HasWriterListeners() )
DelFrames(nullptr);
+ ResetAttr(RES_PAGEDESC);
}
/// allow reaction on change of content of GraphicObject
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index e418e1a36b32..ebddb8ebab27 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -671,27 +671,7 @@ SwFormatPageDesc* SwFormatPageDesc::Clone( SfxItemPool* ) const
void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
{
- if(auto pLegacy = dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
- {
- if(m_pDefinedIn && RES_OBJECTDYING == pLegacy->GetWhich())
- {
- //The Pagedesc where I'm registered dies, therefore I unregister
- //from that format. During this I get deleted!
- if(typeid(SwFormat) == typeid(m_pDefinedIn))
- {
- bool const bResult = static_cast<SwFormat*>(m_pDefinedIn)->ResetFormatAttr(RES_PAGEDESC);
- SAL_WARN_IF(!bResult, "sw.core", "FormatPageDesc not deleted in format.");
- }
- else if(typeid(SwContentNode) == typeid(m_pDefinedIn))
- {
- bool const bResult = static_cast<SwContentNode*>(m_pDefinedIn)->ResetAttr(RES_PAGEDESC);
- SAL_WARN_IF(!bResult, "sw.core", "FormatPageDesc not deleted in content node.");
- }
- else
- SAL_WARN("sw.core", "SwFormatPageDesc defined in object of unknown type");
- }
- }
- else if (const SwPageDescHint* pHint = dynamic_cast<const SwPageDescHint*>(&rHint))
+ if (const SwPageDescHint* pHint = dynamic_cast<const SwPageDescHint*>(&rHint))
{
// mba: shouldn't that be broadcasted also?
SwFormatPageDesc aDfltDesc(pHint->GetPageDesc());
@@ -705,7 +685,7 @@ void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
const_cast<SwFormat*>(pFormat)->SetFormatAttr( aDfltDesc );
else
{
- SAL_WARN("sw.core", "What kind of sw::BroadcastingModify is this?");
+ SAL_WARN("sw.core", "SwFormatPageDesc registered at " << typeid(pMod).name() << ".");
RegisterToPageDesc(*pDesc);
}
}
@@ -713,6 +693,14 @@ void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
// there could be an Undo-copy
RegisterToPageDesc(*pDesc);
}
+ else if(auto pLegacy = dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
+ {
+ if(RES_OBJECTDYING == pLegacy->GetWhich())
+ {
+ m_pDefinedIn = nullptr;
+ EndListeningAll();
+ }
+ }
}
void SwFormatPageDesc::RegisterToPageDesc( SwPageDesc& rDesc )
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index c82128f65ab6..ee05b9a2779b 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -238,6 +238,7 @@ SwOLENode::SwOLENode( const SwNodeIndex &rWhere,
SwOLENode::~SwOLENode()
{
DisconnectFileLink_Impl();
+ ResetAttr(RES_PAGEDESC);
}
const Graphic* SwOLENode::GetGraphic()
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index e71ea4b76119..10c2eb393fdd 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -254,6 +254,7 @@ SwTextNode::~SwTextNode()
InitSwParaStatistics( false );
DelFrames(nullptr); // must be called here while it's still a SwTextNode
DelFrames_TextNodePart();
+ ResetAttr(RES_PAGEDESC);
}
void SwTextNode::FileLoadedInitHints()