Bug 800838 - Guard against invalid NPP when unscheduling plugin timers on Android r=blassey a=bajaj
authorJames Willcox <jwillcox@mozilla.com>
Wed, 23 Jan 2013 09:16:26 -0500
changeset 127341 77cd4578a8691ebc9c7c37698d81821b572b6b5e
parent 127340 08cf71e048a7dc23313c45236c015381491128ec
child 127342 d92c363a82172d3667e743354c4684faa4650845
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey, bajaj
bugs800838
milestone20.0a2
Bug 800838 - Guard against invalid NPP when unscheduling plugin timers on Android r=blassey a=bajaj
dom/plugins/base/nsNPAPIPlugin.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -2804,17 +2804,23 @@ uint32_t NP_CALLBACK
     return 0;
 
   return inst->ScheduleTimer(interval, repeat, timerFunc);
 }
 
 void NP_CALLBACK
 _unscheduletimer(NPP instance, uint32_t timerID)
 {
+#ifdef MOZ_WIDGET_ANDROID
+  // Sometimes Flash calls this with a dead NPP instance. Ensure the one we have
+  // here is valid and maps to a nsNPAPIPluginInstance.
+  nsNPAPIPluginInstance *inst = nsNPAPIPluginInstance::GetFromNPP(instance);
+#else
   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
+#endif
   if (!inst)
     return;
 
   inst->UnscheduleTimer(timerID);
 }
 
 NPError NP_CALLBACK
 _popupcontextmenu(NPP instance, NPMenu* menu)
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -146,16 +146,18 @@ public:
   }
 
 private:
   TextureInfo mTextureInfo;
  
   Mutex mLock;
 };
 
+static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap;
+
 #endif
 
 using namespace mozilla;
 using namespace mozilla::plugins::parent;
 using namespace mozilla::layers;
 
 static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
 
@@ -185,22 +187,30 @@ nsNPAPIPluginInstance::nsNPAPIPluginInst
   , mOnScreen(true)
 #endif
   , mHaveJavaC2PJSObjectQuirk(false)
 {
   mNPP.pdata = NULL;
   mNPP.ndata = this;
 
   PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
+
+#ifdef MOZ_WIDGET_ANDROID
+  sPluginNPPMap[&mNPP] = this;
+#endif
 }
 
 nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
 {
   PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this));
 
+#ifdef MOZ_WIDGET_ANDROID
+  sPluginNPPMap.erase(&mNPP);
+#endif
+
   if (mMIMEType) {
     PR_Free((void *)mMIMEType);
     mMIMEType = nullptr;
   }
 }
 
 uint32_t nsNPAPIPluginInstance::gInPluginCalls = 0;
 
@@ -1047,16 +1057,27 @@ void nsNPAPIPluginInstance::GetVideos(ns
 void nsNPAPIPluginInstance::SetInverted(bool aInverted)
 {
   if (aInverted == mInverted)
     return;
 
   mInverted = aInverted;
 }
 
+nsNPAPIPluginInstance* nsNPAPIPluginInstance::GetFromNPP(NPP npp)
+{
+  std::map<NPP, nsNPAPIPluginInstance*>::iterator it;
+
+  it = sPluginNPPMap.find(npp);
+  if (it == sPluginNPPMap.end())
+    return nullptr;
+
+  return it->second;
+}
+
 #endif
 
 nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel)
 {
 #if defined(XP_MACOSX)
   *aModel = (int32_t)mDrawingModel;
   return NS_OK;
 #else
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -202,16 +202,18 @@ public:
   void* AcquireVideoWindow();
   void ReleaseVideoWindow(void* aWindow);
   void SetVideoDimensions(void* aWindow, gfxRect aDimensions);
 
   void GetVideos(nsTArray<VideoInfo*>& aVideos);
 
   void SetInverted(bool aInverted);
   bool Inverted() { return mInverted; }
+
+  static nsNPAPIPluginInstance* GetFromNPP(NPP npp);
 #endif
 
   nsresult NewStreamListener(const char* aURL, void* notifyData,
                              nsNPAPIPluginStreamListener** listener);
 
   nsNPAPIPluginInstance();
   virtual ~nsNPAPIPluginInstance();