summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mst@openoffice.org>2012-09-18 14:19:50 +0200
committerMichael Stahl <mst@openoffice.org>2012-09-18 14:48:02 +0200
commitcf842d7c7f9559bfdbb3924cd05a3a50d1dff5e3 (patch)
treebc519a89d9325e54966c6540ea0b536bcb5de09d
parent2c933f90e3bc056b7094744d1512bd068dbf8d36 (diff)
rhbz#852128: sw: avoid table undo crash:
SwUndoTblNdsChg::UndoImpl: to prevent access of deleted table box start node, disconnect the SwTableBox from the start node before removing the table box nodes. This problem was probably introduced with CWS swnewtable db4de0817df6906db2743239d45f9f0834ab1e91, which changed the order of the removal operations for unknown reasons. Change-Id: Ic59823a84082cc6ff453b2b512cbb8253886ecf3
-rw-r--r--sw/inc/swtable.hxx1
-rw-r--r--sw/source/core/table/swtable.cxx14
-rw-r--r--sw/source/core/undo/untbl.cxx5
3 files changed, 17 insertions, 3 deletions
diff --git a/sw/inc/swtable.hxx b/sw/inc/swtable.hxx
index 600da7df7a09..0a887c679918 100644
--- a/sw/inc/swtable.hxx
+++ b/sw/inc/swtable.hxx
@@ -431,6 +431,7 @@ public:
SwFrmFmt* ClaimFrmFmt();
void ChgFrmFmt( SwTableBoxFmt *pNewFmt );
+ void RemoveFromTable();
const SwStartNode *GetSttNd() const { return pSttNd; }
sal_uLong GetSttIdx() const;
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
index 5ea5db313b26..5784ada575c9 100644
--- a/sw/source/core/table/swtable.cxx
+++ b/sw/source/core/table/swtable.cxx
@@ -1724,10 +1724,9 @@ SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, const SwStartNode& rSttNd, SwTableL
rSrtArr.insert( p ); // insert
}
-SwTableBox::~SwTableBox()
+void SwTableBox::RemoveFromTable()
{
- // box containing contents?
- if( !GetFrmFmt()->GetDoc()->IsInDtor() && pSttNd )
+ if (pSttNd) // box containing contents?
{
// remove from table
const SwTableNode* pTblNd = pSttNd->FindTableNode();
@@ -1736,6 +1735,15 @@ SwTableBox::~SwTableBox()
GetTabSortBoxes();
SwTableBox *p = this; // error: &this
rSrtArr.erase( p ); // remove
+ pSttNd = 0; // clear it so this is only run once
+ }
+}
+
+SwTableBox::~SwTableBox()
+{
+ if (!GetFrmFmt()->GetDoc()->IsInDtor())
+ {
+ RemoveFromTable();
}
// the TabelleBox can be deleted if it's the last client of the FrameFormat
diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx
index 27e398359300..e5e4f0b2ac50 100644
--- a/sw/source/core/undo/untbl.cxx
+++ b/sw/source/core/undo/untbl.cxx
@@ -1758,7 +1758,11 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, sal_False );
}
else
+ { // first disconnect box from node, otherwise ~SwTableBox would
+ // access pBox->pSttNd, deleted by DeleteSection
+ pBox->RemoveFromTable();
rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
+ }
aDelBoxes.insert( aDelBoxes.end(), pBox );
}
}
@@ -1774,6 +1778,7 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
// TL_CHART2: notify chart about box to be removed
if (pPCD)
pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
+ pBox->RemoveFromTable(); // ~SwTableBox would access pBox->pSttNd
aDelBoxes.insert( aDelBoxes.end(), pBox );
rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
}