summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-10-08 13:34:46 +0100
committerCaolán McNamara <caolanm@redhat.com>2015-10-08 13:40:24 +0100
commitf1f0d12674ed362dc38ae2ed8c8a44ed97d7555e (patch)
tree59ff6b6c057ba0905ee826c5cc23d60efae3b61e
parent5c4fbedf29a88171ad4ecf600d8e80105675234d (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
-rw-r--r--sw/source/core/inc/flowfrm.hxx33
-rw-r--r--sw/source/core/layout/flowfrm.cxx8
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 );
}