diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-06-08 11:51:21 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-06-08 16:15:56 +0200 |
commit | 8d1627ff8aeb0eb128d93d9bf8c1d9b373edbf4a (patch) | |
tree | ad0d072296dd58d9d8ef63f2c76ada940d32bb21 /sw | |
parent | b8626e85a799fd0807749cab9e712652240f13cd (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.cxx | 16 |
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) |