Bug 1264530 - Hold on to Plugin Instance to survive frame poisoning. r=jimm,a=sledru
authorBenoit Girard <b56girard@gmail.com>
Wed, 10 Aug 2016 16:21:01 -0400
changeset 407644 e360efec6839e500742b9112e798b56f1d3eb4e7
parent 407643 4cc7ecd49f95a67ccd0335c5e5264501285ca6d4
child 407645 f36f7ace6f487e06f315f343d560b205fa8bd736
push id28002
push userfelipc@gmail.com
push dateTue, 30 Aug 2016 18:14:28 +0000
reviewersjimm, sledru
bugs1264530
milestone48.0.1
Bug 1264530 - Hold on to Plugin Instance to survive frame poisoning. r=jimm,a=sledru MozReview-Commit-ID: JHbce46rDBN
layout/generic/nsPluginFrame.cpp
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -638,31 +638,34 @@ nsPluginFrame::CallSetWindow(bool aCheck
   // In e10s, this returns the offset to the top level window, in non-e10s
   // it return 0,0.
   LayoutDeviceIntPoint intOffset = GetRemoteTabChromeOffset();
   intBounds.x += intOffset.x;
   intBounds.y += intOffset.y;
 
   // window must be in "display pixels"
   double scaleFactor = 1.0;
-  if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) {
+  if (NS_FAILED(instanceOwnerRef->GetContentsScaleFactor(&scaleFactor))) {
     scaleFactor = 1.0;
   }
   size_t intScaleFactor = ceil(scaleFactor);
   window->x = intBounds.x / intScaleFactor;
   window->y = intBounds.y / intScaleFactor;
   window->width = intBounds.width / intScaleFactor;
   window->height = intBounds.height / intScaleFactor;
 
-  mInstanceOwner->ResolutionMayHaveChanged();
+  // BE CAREFUL: By the time we get here the PluginFrame is sometimes destroyed
+  // and poisoned. If we reference local fields (implicit this deref),
+  // we will crash.
+  instanceOwnerRef->ResolutionMayHaveChanged();
 
   // This will call pi->SetWindow and take care of window subclassing
   // if needed, see bug 132759. Calling SetWindow can destroy this frame
   // so check for that before doing anything else with this frame's memory.
-  if (mInstanceOwner->UseAsyncRendering()) {
+  if (instanceOwnerRef->UseAsyncRendering()) {
     rv = pi->AsyncSetWindow(window);
   }
   else {
     rv = window->CallSetWindow(pi);
   }
 
   instanceOwnerRef->ReleasePluginPort(window->window);