summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-07-21 12:01:01 +0200
committerAndras Timar <andras.timar@collabora.com>2017-07-31 12:03:55 +0200
commit7c9479bcf7eb16293f83a0e91a7e57678b935dec (patch)
tree3f8a638f45d94791fc062b321441dc9b0b5d4c2d
parent0a11bff8109f14f227aa1d27e35637472e0d5f23 (diff)
tdf#108867 sw: fix dangling text box frame format pointers in Undo
If the text box is removed, the SwFrameFormat of the drawing shape still retains a pointer to the frame SwFrameFormat, and the latter is owned by the SwUndoFlyBase. This is pretty bad, so try to clear & reset the connection between them in SwUndoFlyBase::InsFly() and DelFly(). Hopefully nothing will actually delete the drawing shape SwFrameFormat while the Undo object is alive. Note that when the SwUndoInsLayFormat is created when the text box is added, the GetOtherTextBoxFormat() returns null as it's set later, that's why the constructor can't do anything. Change-Id: Iae562b6f8f272e47b2b5cf8ee80778db15d29ce0 (cherry picked from commit 2e486daff35ab16e810bfdafb24b19bcbf2fe8cd) Reviewed-on: https://gerrit.libreoffice.org/40283 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit b39cb50c6afb47f39b21c3fb3ea913b902632924)
-rw-r--r--sw/inc/frmfmt.hxx1
-rw-r--r--sw/source/core/undo/undobj1.cxx18
2 files changed, 19 insertions, 0 deletions
diff --git a/sw/inc/frmfmt.hxx b/sw/inc/frmfmt.hxx
index 22db10be7030..3dad36d67691 100644
--- a/sw/inc/frmfmt.hxx
+++ b/sw/inc/frmfmt.hxx
@@ -44,6 +44,7 @@ class SW_DLLPUBLIC SwFrameFormat: public SwFormat
friend class ::sw::DocumentLayoutManager; ///< Is allowed to call protected CTor.
friend class SwFrameFormats; ///< Is allowed to update the list backref.
friend class SwTextBoxHelper;
+ friend class SwUndoFlyBase; ///< calls SetOtherTextBoxFormat
css::uno::WeakReference<css::uno::XInterface> m_wXObject;
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx
index ed97d013c904..d12874d98bbe 100644
--- a/sw/source/core/undo/undobj1.cxx
+++ b/sw/source/core/undo/undobj1.cxx
@@ -52,7 +52,13 @@ SwUndoFlyBase::SwUndoFlyBase( SwFrameFormat* pFormat, SwUndoId nUndoId )
SwUndoFlyBase::~SwUndoFlyBase()
{
if( bDelFormat ) // delete during an Undo?
+ {
+ if (pFrameFormat->GetOtherTextBoxFormat())
+ { // clear that before delete
+ pFrameFormat->SetOtherTextBoxFormat(nullptr);
+ }
delete pFrameFormat;
+ }
}
void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrame)
@@ -117,6 +123,13 @@ void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrame)
pCNd->GetTextNode()->InsertItem(aFormat, nCntPos, nCntPos, SetAttrMode::NOHINTEXPAND);
}
+ if (pFrameFormat->GetOtherTextBoxFormat())
+ {
+ // recklessly assume that this thing will live longer than the
+ // SwUndoFlyBase - not sure what could be done if that isn't the case...
+ pFrameFormat->GetOtherTextBoxFormat()->SetOtherTextBoxFormat(pFrameFormat);
+ }
+
pFrameFormat->MakeFrames();
if( bShowSelFrame )
@@ -155,6 +168,11 @@ void SwUndoFlyBase::DelFly( SwDoc* pDoc )
bDelFormat = true; // delete Format in DTOR
pFrameFormat->DelFrames(); // destroy Frames
+ if (pFrameFormat->GetOtherTextBoxFormat())
+ { // tdf#108867 clear that pointer
+ pFrameFormat->GetOtherTextBoxFormat()->SetOtherTextBoxFormat(nullptr);
+ }
+
// all Uno objects should now log themselves off
{
SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFrameFormat );