summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2013-11-08 14:53:42 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-11-08 17:18:29 +0000
commitb376eacdfae11f5d39eb7011efe67390d9f495e7 (patch)
tree007ff21462fbbfd42beede45b3143b7e87b32542
parent050d2ceb534f17f3e865f5f8118bb95a4749de9c (diff)
Access by AnchoredObject of a deleted SwLayoutFrm
as demonstrated by abi10075-1.doc just register the AnchoredObjects in the SwLayoutFrm and inform them when the SwLayoutFrm goes away. This crash was triggered by "1e113cb7604e1509e7d598a9be329f1f7b6e9322" import different first page header/footer from doc. But that commit is blameless. Change-Id: Ia079cc635a81dff1ccbf740641f441aa784328a4
-rw-r--r--sw/inc/anchoredobject.hxx7
-rw-r--r--sw/source/core/inc/layfrm.hxx14
-rw-r--r--sw/source/core/layout/anchoredobject.cxx12
-rw-r--r--sw/source/core/layout/ssfrm.cxx8
4 files changed, 36 insertions, 5 deletions
diff --git a/sw/inc/anchoredobject.hxx b/sw/inc/anchoredobject.hxx
index 7e304fdac829..da66dcafe814 100644
--- a/sw/inc/anchoredobject.hxx
+++ b/sw/inc/anchoredobject.hxx
@@ -269,15 +269,12 @@ class SW_DLLPUBLIC SwAnchoredObject
// accessors to data of position calculation:
// frame vertical position is orient at
- inline const SwLayoutFrm* GetVertPosOrientFrm() const
+ const SwLayoutFrm* GetVertPosOrientFrm() const
{
return mpVertPosOrientFrm;
}
// method to clear member <mpVertPosOrientFrm>
- inline void ClearVertPosOrientFrm()
- {
- mpVertPosOrientFrm = 0L;
- }
+ void ClearVertPosOrientFrm();
/** check anchor character rectangle and top of line
diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx
index 30af36c8e9aa..87c823dccc1a 100644
--- a/sw/source/core/inc/layfrm.hxx
+++ b/sw/source/core/inc/layfrm.hxx
@@ -21,6 +21,7 @@
#include "frame.hxx"
+class SwAnchoredObject;
class SwCntntFrm;
class SwFlowFrm;
class SwFmtCol;
@@ -53,6 +54,7 @@ protected:
virtual void MakeAll();
SwFrm *pLower;
+ std::vector<SwAnchoredObject*> aVertPosOrientFrmsFor;
virtual SwTwips ShrinkFrm( SwTwips, sal_Bool bTst = sal_False, sal_Bool bInfo = sal_False );
virtual SwTwips GrowFrm ( SwTwips, sal_Bool bTst = sal_False, sal_Bool bInfo = sal_False );
@@ -164,6 +166,18 @@ public:
inline SwFrm* GetLastLower();
virtual void PaintBreak() const;
+
+ void SetVertPosOrientFrmFor(SwAnchoredObject *pObj)
+ {
+ aVertPosOrientFrmsFor.push_back(pObj);
+ }
+
+ void ClearVertPosOrientFrmFor(SwAnchoredObject *pObj)
+ {
+ aVertPosOrientFrmsFor.erase(
+ std::remove(aVertPosOrientFrmsFor.begin(),
+ aVertPosOrientFrmsFor.end(), pObj), aVertPosOrientFrmsFor.end());
+ }
};
//Um doppelte Implementierung zu sparen wird hier ein bischen gecasted
diff --git a/sw/source/core/layout/anchoredobject.cxx b/sw/source/core/layout/anchoredobject.cxx
index b7379986ed26..157c3468581a 100644
--- a/sw/source/core/layout/anchoredobject.cxx
+++ b/sw/source/core/layout/anchoredobject.cxx
@@ -98,8 +98,18 @@ SwAnchoredObject::SwAnchoredObject() :
{
}
+void SwAnchoredObject::ClearVertPosOrientFrm()
+{
+ if (mpVertPosOrientFrm)
+ {
+ const_cast<SwLayoutFrm*>(mpVertPosOrientFrm)->ClearVertPosOrientFrmFor(this);
+ mpVertPosOrientFrm = NULL;
+ }
+}
+
SwAnchoredObject::~SwAnchoredObject()
{
+ ClearVertPosOrientFrm();
}
// =============================================================================
@@ -229,6 +239,8 @@ void SwAnchoredObject::SetVertPosOrientFrm( const SwLayoutFrm& _rVertPosOrientFr
{
mpVertPosOrientFrm = &_rVertPosOrientFrm;
+ const_cast<SwLayoutFrm*>(mpVertPosOrientFrm)->SetVertPosOrientFrmFor(this);
+
// #i28701# - take over functionality of deleted method
// <SwFlyAtCntFrm::AssertPage()>: assure for at-paragraph and at-character
// an anchored object, that it is registered at the correct page frame
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index ffd6da9bda51..e44893be92b9 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -557,6 +557,14 @@ void SwCntntFrm::DelFrms( const SwCntntNode& rNode )
void SwLayoutFrm::Destroy()
{
+ while (!aVertPosOrientFrmsFor.empty())
+ {
+ SwAnchoredObject *pObj = *aVertPosOrientFrmsFor.begin();
+ pObj->ClearVertPosOrientFrm();
+ }
+
+ assert(aVertPosOrientFrmsFor.empty());
+
SwFrm *pFrm = pLower;
if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )