summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-06-08 11:51:21 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-06-08 16:15:56 +0200
commit8d1627ff8aeb0eb128d93d9bf8c1d9b373edbf4a (patch)
treead0d072296dd58d9d8ef63f2c76ada940d32bb21 /sw
parentb8626e85a799fd0807749cab9e712652240f13cd (diff)
sw: fix use-after-free in SwFrame::ImplFindPageFrame()
Header-footer controls have a non-owning pointer to their page frames in Writer views, so whenever a page frame gets deleted, we need to manually make sure that the header-footer control doesn't have a pointer to the deleted page frame. This already works with a single view, but in case one view has a visible header-footer control and an other view deletes the page frame that is known to the header-footer control, then we have a problem. Fix the problematic outdated SwFrameMenuButtonBase::m_pFrame by extending SwPageFrame::DestroyImpl(), so it un-registers itself (before deletion) not only from the current view, but from all views. Found by online.git's: tst=/tmp/testfoo.odt cp test/data/hello-world.odt $tst ./coolstress wss://localhost:9980 $tst test/traces/writer-hello-shape.txt $tst test/traces/writer-document-edit.txt $tst test/traces/writer-mash-text-table.txt $tst test/traces/writer-rambling-text-table.txt $tst test/traces/writer-add-bullet.txt although also reproducible on the desktop, in case you have two views (windows), do cltr-enter to have 2 pages, go to the 2nd page in both views, view 1 clicks on the 2nd page's header, view 2 deletes the page (backspace) and finally view 1 clicks in the body text of the current page. Change-Id: I35e5d82256ab5db8e5f0ba198f5d2638cbff7d3c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135489 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/layout/pagechg.cxx16
1 files changed, 11 insertions, 5 deletions
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index e7a458737d30..a76b9a379a33 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -255,13 +255,19 @@ SwPageFrame::SwPageFrame( SwFrameFormat *pFormat, SwFrame* pSib, SwPageDesc *pPg
void SwPageFrame::DestroyImpl()
{
- // Cleanup the header-footer controls in the SwEditWin
+ // Cleanup the header-footer controls in all SwEditWins
SwViewShell* pSh = getRootFrame()->GetCurrShell();
- SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pSh );
- if ( pWrtSh )
+ if (pSh)
{
- SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
- rEditWin.GetFrameControlsManager( ).RemoveControls( this );
+ for (SwViewShell& rSh : pSh->GetRingContainer())
+ {
+ SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( &rSh );
+ if ( pWrtSh )
+ {
+ SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
+ rEditWin.GetFrameControlsManager( ).RemoveControls( this );
+ }
+ }
}
// empty FlyContainer, deletion of the Flys is done by the anchor (in base class SwFrame)