diff options
author | Michael Stahl <mstahl@redhat.com> | 2014-05-05 21:30:43 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2014-05-05 23:54:22 +0200 |
commit | a82de8698a4569d043a3f656a4afbe21a952f8d3 (patch) | |
tree | b8e30cb92556f494f09702bc59a49e68f2cf8da1 | |
parent | cd83ef996b09907d669d686d1a33db5a8f08f72d (diff) |
fdo#57197: sw: fix crash on Undo of table row insert on 1-row table
... with accessibility enabled: the SwCellFrms are deleted, but the
entry in the SwAccessibleMap::mpFrmMap is not removed, because Dispose
returns early since the connections to the nodes have been severed already.
This then crashes in some questionable code that iterates over and uses
the frame pointers in mpFrmMap that was added in
76c549eb01dcb7b5bf28a271ce00e386f3d388ba (where previously only the
WeakReferences were used out of that map).
Change-Id: I13885c6ab9a92e34e95925f275e15c20fdc600b7
-rw-r--r-- | sw/source/core/undo/untbl.cxx | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx index bfdcb559cdb6..e1d4833bd85e 100644 --- a/sw/source/core/undo/untbl.cxx +++ b/sw/source/core/undo/untbl.cxx @@ -1690,6 +1690,7 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) SwChartDataProvider *pPCD = rDoc.GetChartDataProvider(); SwSelBoxes aDelBoxes; + std::vector< std::pair<SwTableBox *, sal_uLong> > aDelNodes; if( IsDelBox() ) { // Trick: add missing boxes in any line, they will be connected @@ -1754,10 +1755,8 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, false ); } else - { // first disconnect box from node, otherwise ~SwTableBox would - // access pBox->pSttNd, deleted by DeleteSection - pBox->RemoveFromTable(); - rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] ); + { + aDelNodes.push_back(std::make_pair(pBox, nIdx)); } } } @@ -1774,8 +1773,7 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) if (pPCD) pPCD->DeleteBox( &pTblNd->GetTable(), *pBox ); aDelBoxes.insert(pBox); - pBox->RemoveFromTable(); // ~SwTableBox would access pBox->pSttNd - rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] ); + aDelNodes.push_back(std::make_pair(pBox, nIdx)); } } @@ -1783,6 +1781,16 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext) aTmpBox.SetTableLines(aDelBoxes, pTblNd->GetTable()); aTmpBox.DelFrms(pTblNd->GetTable()); + // do this _after_ deleting Frms because disposing SwAccessible requires + // connection to the nodes, see SwAccessibleChild::IsAccessible() + for (size_t i = 0; i < aDelNodes.size(); ++i) + { + // first disconnect box from node, otherwise ~SwTableBox would + // access pBox->pSttNd, deleted by DeleteSection + aDelNodes[i].first->RemoveFromTable(); + rDoc.DeleteSection(rDoc.GetNodes()[ aDelNodes[i].second ]); + } + // Remove boxes from table structure for( sal_uInt16 n = 0; n < aDelBoxes.size(); ++n ) { |