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
db4de0817d
, which changed the order of the
removal operations for unknown reasons.
Change-Id: Ic59823a84082cc6ff453b2b512cbb8253886ecf3
This commit is contained in:
@@ -431,6 +431,7 @@ public:
|
|||||||
SwFrmFmt* ClaimFrmFmt();
|
SwFrmFmt* ClaimFrmFmt();
|
||||||
void ChgFrmFmt( SwTableBoxFmt *pNewFmt );
|
void ChgFrmFmt( SwTableBoxFmt *pNewFmt );
|
||||||
|
|
||||||
|
void RemoveFromTable();
|
||||||
const SwStartNode *GetSttNd() const { return pSttNd; }
|
const SwStartNode *GetSttNd() const { return pSttNd; }
|
||||||
sal_uLong GetSttIdx() const;
|
sal_uLong GetSttIdx() const;
|
||||||
|
|
||||||
|
@@ -1724,10 +1724,9 @@ SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, const SwStartNode& rSttNd, SwTableL
|
|||||||
rSrtArr.insert( p ); // insert
|
rSrtArr.insert( p ); // insert
|
||||||
}
|
}
|
||||||
|
|
||||||
SwTableBox::~SwTableBox()
|
void SwTableBox::RemoveFromTable()
|
||||||
{
|
{
|
||||||
// box containing contents?
|
if (pSttNd) // box containing contents?
|
||||||
if( !GetFrmFmt()->GetDoc()->IsInDtor() && pSttNd )
|
|
||||||
{
|
{
|
||||||
// remove from table
|
// remove from table
|
||||||
const SwTableNode* pTblNd = pSttNd->FindTableNode();
|
const SwTableNode* pTblNd = pSttNd->FindTableNode();
|
||||||
@@ -1736,6 +1735,15 @@ SwTableBox::~SwTableBox()
|
|||||||
GetTabSortBoxes();
|
GetTabSortBoxes();
|
||||||
SwTableBox *p = this; // error: &this
|
SwTableBox *p = this; // error: &this
|
||||||
rSrtArr.erase( p ); // remove
|
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
|
// the TabelleBox can be deleted if it's the last client of the FrameFormat
|
||||||
|
@@ -1758,7 +1758,11 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
|
|||||||
rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, sal_False );
|
rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, sal_False );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{ // first disconnect box from node, otherwise ~SwTableBox would
|
||||||
|
// access pBox->pSttNd, deleted by DeleteSection
|
||||||
|
pBox->RemoveFromTable();
|
||||||
rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
|
rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
|
||||||
|
}
|
||||||
aDelBoxes.insert( aDelBoxes.end(), pBox );
|
aDelBoxes.insert( aDelBoxes.end(), pBox );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1774,6 +1778,7 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
|
|||||||
// TL_CHART2: notify chart about box to be removed
|
// TL_CHART2: notify chart about box to be removed
|
||||||
if (pPCD)
|
if (pPCD)
|
||||||
pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
|
pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
|
||||||
|
pBox->RemoveFromTable(); // ~SwTableBox would access pBox->pSttNd
|
||||||
aDelBoxes.insert( aDelBoxes.end(), pBox );
|
aDelBoxes.insert( aDelBoxes.end(), pBox );
|
||||||
rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
|
rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user