diff options
author | Caolán McNamara <caolanm@redhat.com> | 2013-11-08 14:53:42 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-11-08 17:18:29 +0000 |
commit | b376eacdfae11f5d39eb7011efe67390d9f495e7 (patch) | |
tree | 007ff21462fbbfd42beede45b3143b7e87b32542 /sw | |
parent | 050d2ceb534f17f3e865f5f8118bb95a4749de9c (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
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/anchoredobject.hxx | 7 | ||||
-rw-r--r-- | sw/source/core/inc/layfrm.hxx | 14 | ||||
-rw-r--r-- | sw/source/core/layout/anchoredobject.cxx | 12 | ||||
-rw-r--r-- | sw/source/core/layout/ssfrm.cxx | 8 |
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() ) |