diff options
author | Caolán McNamara <caolanm@redhat.com> | 2015-10-08 13:34:46 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-10-08 13:40:24 +0100 |
commit | f1f0d12674ed362dc38ae2ed8c8a44ed97d7555e (patch) | |
tree | 59ff6b6c057ba0905ee826c5cc23d60efae3b61e /sw | |
parent | 5c4fbedf29a88171ad4ecf600d8e80105675234d (diff) |
restore FlowFrmJoinLockGuard for surviving layout of ooo77837-1.odt
ubsan and valgrind continue to report use after delete of SwSectionFrm
with the same error message listed in the original commit of
commit c3087d969671e62182eb049850479e77190ccff4
avoid crash on layout of ooo77837-1.odt
by attempting to set the parent as un-joinable for the duration of the
Cut/Paste in order to ensure it survives the process
which introduced FlowFrmJoinLockGuard
continue to use lighter weight SwFrmDeleteGuard where we can get away with
doing that.
Change-Id: Ifb4c69514d074c776ec036987153043d1f715b95
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/inc/flowfrm.hxx | 33 | ||||
-rw-r--r-- | sw/source/core/layout/flowfrm.cxx | 8 |
2 files changed, 37 insertions, 4 deletions
diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx index 7c0e9b808dad..6421a9efc6bd 100644 --- a/sw/source/core/inc/flowfrm.hxx +++ b/sw/source/core/inc/flowfrm.hxx @@ -62,6 +62,7 @@ class SwFlowFrm friend inline void TableSplitRecalcUnlock( SwFlowFrm * ); // #i44049# friend class SwObjectFormatterTextFrm; + friend class FlowFrmJoinLockGuard; // TableSel is allowed to reset the follow-bit friend inline void UnsetFollow( SwFlowFrm *pFlow ); @@ -235,6 +236,38 @@ inline bool SwFlowFrm::IsFwdMoveAllowed() return m_rThis.GetIndPrev() != 0; } +//use this to protect a SwLayoutFrm for a given scope from getting merged with +//its neighbour and thus deleted +class FlowFrmJoinLockGuard +{ +private: + SwFlowFrm *m_pFlow; + bool m_bOldJoinLocked; +public: + //JoinLock pParent for the lifetime of the Cut/Paste call, etc. to avoid + //SwSectionFrm::MergeNext removing the pParent we're trying to reparent + //into + FlowFrmJoinLockGuard(SwLayoutFrm* pFrm) + { + m_pFlow = SwFlowFrm::CastFlowFrm(pFrm); + if (m_pFlow) + { + m_bOldJoinLocked = m_pFlow->IsJoinLocked(); + m_pFlow->LockJoin(); + } + else + { + m_bOldJoinLocked = false; + } + } + + ~FlowFrmJoinLockGuard() + { + if (m_pFlow && !m_bOldJoinLocked) + m_pFlow->UnlockJoin(); + } +}; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index 5ba115f30d5d..99376c43adfe 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -577,10 +577,10 @@ void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling ) bool bInvaLay; { - //Ensure pParent persists for the lifetime of the Cut/Paste call to - //avoid SwSectionFrm::MergeNext removing the pParent we're trying to - //reparent into - SwFrmDeleteGuard aDeleteGuard(pParent); + //JoinLock pParent for the lifetime of the Cut/Paste call to avoid + //SwSectionFrm::MergeNext removing the pParent we're trying to reparent + //into + FlowFrmJoinLockGuard aJoinGuard(pParent); pOldParent = CutTree( &m_rThis ); bInvaLay = PasteTree( &m_rThis, pParent, pSibling, pOldParent ); } |