From 1af2f3576f0c3c98e0680ba26e8ae751fdfb538c Mon Sep 17 00:00:00 2001 From: Benjamin Smedberg Date: Wed, 23 Jun 2010 10:18:00 -0400 Subject: [PATCH] Bug 449129 - abort a plugin process if a plugin attempts to spin an event loop while painting, r=jmathies --- dom/plugins/PluginInstanceChild.cpp | 4 ++++ dom/plugins/PluginInstanceChild.h | 2 ++ ipc/glue/WindowsMessageLoop.cpp | 5 +++++ layout/base/Makefile.in | 7 +++++++ layout/base/PaintTracker.cpp | 7 +++++++ layout/base/PaintTracker.h | 29 +++++++++++++++++++++++++++++ 6 files changed, 54 insertions(+) create mode 100644 layout/base/PaintTracker.cpp create mode 100644 layout/base/PaintTracker.h diff --git a/dom/plugins/PluginInstanceChild.cpp b/dom/plugins/PluginInstanceChild.cpp index 8ee2fc75c094..861c75668dd8 100644 --- a/dom/plugins/PluginInstanceChild.cpp +++ b/dom/plugins/PluginInstanceChild.cpp @@ -615,6 +615,8 @@ PluginInstanceChild::AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event, PLUGIN_LOG_DEBUG_FUNCTION; AssertPluginThread(); + PaintTracker pt; + NPCocoaEvent evcopy = event.event; if (evcopy.type == NPCocoaEventDrawRect) { @@ -686,6 +688,8 @@ PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event, PLUGIN_LOG_DEBUG_FUNCTION; AssertPluginThread(); + PaintTracker pt; + NPCocoaEvent evcopy = event.event; nsIOSurface* surf = nsIOSurface::LookupSurface(surfaceid); if (!surf) { diff --git a/dom/plugins/PluginInstanceChild.h b/dom/plugins/PluginInstanceChild.h index 5ea2157edfcb..42c394eed52b 100644 --- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -56,6 +56,7 @@ #include "ChildTimer.h" #include "nsRect.h" #include "nsTHashtable.h" +#include "mozilla/PaintTracker.h" namespace mozilla { namespace plugins { @@ -100,6 +101,7 @@ class PluginInstanceChild : public PPluginInstanceChild virtual bool AnswerPaint(const NPRemoteEvent& event, int16_t* handled) { + PaintTracker pt; return AnswerNPP_HandleEvent(event, handled); } diff --git a/ipc/glue/WindowsMessageLoop.cpp b/ipc/glue/WindowsMessageLoop.cpp index 27a2a028e0f7..c9c31b223925 100644 --- a/ipc/glue/WindowsMessageLoop.cpp +++ b/ipc/glue/WindowsMessageLoop.cpp @@ -47,6 +47,7 @@ #include "nsIXULAppInfo.h" #include "mozilla/Mutex.h" +#include "mozilla/PaintTracker.h" using mozilla::ipc::SyncChannel; using mozilla::ipc::RPCChannel; @@ -623,6 +624,10 @@ RPCChannel::ProcessNativeEventsInRPCCall() void RPCChannel::SpinInternalEventLoop() { + if (mozilla::PaintTracker::IsPainting()) { + NS_RUNTIMEABORT("Don't spin an event loop while painting."); + } + NS_ASSERTION(mTopFrame && mTopFrame->mSpinNestedEvents, "Spinning incorrectly"); diff --git a/layout/base/Makefile.in b/layout/base/Makefile.in index 34388ff94a86..ee5f612862ce 100644 --- a/layout/base/Makefile.in +++ b/layout/base/Makefile.in @@ -58,6 +58,8 @@ XPIDLSRCS = \ nsIStyleSheetService.idl \ $(NULL) +EXPORTS_NAMESPACES = mozilla + EXPORTS = \ FrameLayerBuilder.h \ FramePropertyTable.h \ @@ -88,6 +90,10 @@ EXPORTS = \ nsStyleConsts.h \ $(NULL) +EXPORTS_mozilla = \ + PaintTracker.h \ + $(NULL) + CPPSRCS = \ FrameLayerBuilder.cpp \ FramePropertyTable.cpp \ @@ -115,6 +121,7 @@ CPPSRCS = \ nsRefreshDriver.cpp \ nsStyleChangeList.cpp \ nsStyleSheetService.cpp \ + PaintTracker.cpp \ $(NULL) ifndef MOZ_XUL diff --git a/layout/base/PaintTracker.cpp b/layout/base/PaintTracker.cpp new file mode 100644 index 000000000000..04c7f39cdaf1 --- /dev/null +++ b/layout/base/PaintTracker.cpp @@ -0,0 +1,7 @@ +#include "mozilla/PaintTracker.h" + +namespace mozilla { + +int PaintTracker::gPaintTracker; + +} // namespace mozilla diff --git a/layout/base/PaintTracker.h b/layout/base/PaintTracker.h new file mode 100644 index 000000000000..02103ff9eac4 --- /dev/null +++ b/layout/base/PaintTracker.h @@ -0,0 +1,29 @@ +#ifndef mozilla_PaintTracker_h +#define mozilla_PaintTracker_h + +#include "nscore.h" +#include "nsDebug.h" + +namespace mozilla { + +class NS_STACK_CLASS PaintTracker +{ +public: + PaintTracker() { + ++gPaintTracker; + } + ~PaintTracker() { + NS_ASSERTION(gPaintTracker > 0, "Mismatched constructor/destructor"); + } + + static bool IsPainting() { + return !!gPaintTracker; + } + +private: + static int gPaintTracker; +}; + +} // namespace mozilla + +#endif // mozilla_PaintTracker_h