Kaydet (Commit) ddf8d9a1 authored tarafından Michael Stahl's avatar Michael Stahl

sw: fix use-after-free in SwAccessibleMap::FireEvents()

As seen when running JunitTest_sw_unoapi_3 against "make debugrun",
the damn thing can call itself recursively via an odd corner case in
GetContext():

0  in SwAccessibleEventList_Impl::~SwAccessibleEventList_Impl() (this=0x9a6a170, __in_chrg=<optimized out>) at sw/source/core/access/accmap.cxx:498
1  in SwAccessibleMap::FireEvents() (this=0x8198bb0) at sw/source/core/access/accmap.cxx:3023
2  in SwAccessibleMap::InvalidateCursorPosition(com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> const&) (this=0x8198bb0, rAcc=uno::Reference to (SwAccessibleParagraph *) 0x9a439d8) at sw/source/core/access/accmap.cxx:1069
3  in SwAccessibleMap::GetContext(SwFrame const*, bool) (this=0x8198bb0, pFrame=0x825ca10, bCreate=true) at sw/source/core/access/accmap.cxx:1925
4  in SwAccessibleMap::GetContextImpl(SwFrame const*, bool) (this=0x8198bb0, pFrame=0x825ca10, bCreate=true) at sw/source/core/access/accmap.cxx:1936
5  in SwAccessibleContext::InvalidateChildPosOrSize(sw::access::SwAccessibleChild const&, SwRect const&) (this=0x405a350, rChildFrameOrObj=..., rOldFrame=SwRect = {...}) at sw/source/core/access/acccontext.cxx:1196
6  in SwAccessibleMap::FireEvent(SwAccessibleEvent_Impl const&) (this=0x8198bb0, rEvent=...) at sw/source/core/access/accmap.cxx:898
7  in SwAccessibleMap::FireEvents() (this=0x8198bb0) at sw/source/core/access/accmap.cxx:3018
8  in SwViewShellImp::FireAccessibleEvents() (this=0x7744dc0) at sw/source/core/view/viewimp.cxx:460
9  in SwLayIdle::SwLayIdle(SwRootFrame*, SwViewShellImp*) (this=0x7ffc63395e30, pRt=0x7745120, pI=0x7744dc0) at sw/source/core/layout/layact.cxx:2267

Presumably all of mpEvents, mpEventMap and mpShapes must live until
the outermost FireEvents() completes.

Change-Id: I4e5a053035bf7fc12d9407913437d721889950ae
üst 789433da
...@@ -3010,6 +3010,11 @@ void SwAccessibleMap::FireEvents() ...@@ -3010,6 +3010,11 @@ void SwAccessibleMap::FireEvents()
osl::MutexGuard aGuard( maEventMutex ); osl::MutexGuard aGuard( maEventMutex );
if( mpEvents ) if( mpEvents )
{ {
if (mpEvents->IsFiring())
{
return; // prevent recursive FireEvents()
}
mpEvents->SetFiring(); mpEvents->SetFiring();
mpEvents->MoveMissingXAccToEnd(); mpEvents->MoveMissingXAccToEnd();
for( auto const& aEvent : *mpEvents ) for( auto const& aEvent : *mpEvents )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment