summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2015-09-30 10:31:23 +0200
committerCaolán McNamara <caolanm@redhat.com>2015-09-30 10:10:27 +0000
commiteb9321d5524bb946fd03cbe28d1c5c44a64f6aa3 (patch)
tree4d46e7414fe1a5b9ddfd931baac1900a5fc14097
parent2d213a44ac71e5df5576463303a5a715e7b1700e (diff)
sc: fix crash in ScVbaEventListener::processWindowResizeEvent()
This was crashing in CppunitTest_sc_macros_test on Windows with --enable-mergelibs (release build), because the first invocation of processWindowResizeEvent() deleted the vcl::Window, and the maControllers.count(pWindow) test creates a VclPtr for it, so ends up with a double-free. TODO: is processWindowResizeEvent() supposed to be idempotent? It would be possible to detect that there is already an event posted by checking m_PostedWindows in postWindowResizeEvent(). Change-Id: I7b72f2baf21bb8223e9fe4bd929d826217b920e5 (cherry picked from commit 520514cfe6a99f68b9e1d458fae20026f1a8f66b) Reviewed-on: https://gerrit.libreoffice.org/19022 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sc/source/ui/vba/vbaeventshelper.cxx13
1 files changed, 10 insertions, 3 deletions
diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx
index e787031b774f..d92f64084006 100644
--- a/sc/source/ui/vba/vbaeventshelper.cxx
+++ b/sc/source/ui/vba/vbaeventshelper.cxx
@@ -169,7 +169,7 @@ private:
uno::Reference< frame::XModel > mxModel;
ScDocShell* mpDocShell;
WindowControllerMap maControllers; /// Maps VCL top windows to their controllers.
- std::set< VclPtr<vcl::Window> > maPostedWindows; /// Keeps processWindowResizeEvent windows from being deleted between postWindowResizeEvent and processWindowResizeEvent
+ std::multiset< VclPtr<vcl::Window> > m_PostedWindows; /// Keeps processWindowResizeEvent windows from being deleted between postWindowResizeEvent and processWindowResizeEvent
VclPtr<vcl::Window> mpActiveWindow; /// Currently activated window, to prevent multiple (de)activation.
bool mbWindowResized; /// True = window resize system event processed.
bool mbBorderChanged; /// True = borders changed system event processed.
@@ -471,7 +471,7 @@ void ScVbaEventListener::postWindowResizeEvent( vcl::Window* pWindow )
{
mbWindowResized = mbBorderChanged = false;
acquire(); // ensure we don't get deleted before the timer fires
- maPostedWindows.insert(pWindow);
+ m_PostedWindows.insert(pWindow);
Application::PostUserEvent( LINK( this, ScVbaEventListener, processWindowResizeEvent ), pWindow );
}
}
@@ -504,7 +504,14 @@ IMPL_LINK( ScVbaEventListener, processWindowResizeEvent, vcl::Window*, pWindow )
}
}
}
- maPostedWindows.erase(pWindow);
+ {
+ // note: there may be multiple processWindowResizeEvent outstanding
+ // for pWindow, so it may have been added to m_PostedWindows multiple
+ // times - so this must delete exactly one of these elements!
+ auto const iter(m_PostedWindows.find(pWindow));
+ assert(iter != m_PostedWindows.end());
+ m_PostedWindows.erase(iter);
+ }
release();
return 0;
}