Title: [148560] trunk/Source/WebCore
Revision
148560
Author
[email protected]
Date
2013-04-16 15:58:03 -0700 (Tue, 16 Apr 2013)

Log Message

PlugIn Snapshotting: Crashes refreshing non-main-frame PDFPlugins
https://bugs.webkit.org/show_bug.cgi?id=114702
<rdar://problem/13542020>

Reviewed by Dean Jackson.

If:

    a) a plugin fails all the tests in willCreatePlugIn, so it is WaitingForSnapshot there
    b) primary plugin detection attempts to restart a plugin between the
       time that willCreatePlugIn and didCreatePlugIn fire
    c) when didCreatePlugIn fires, shouldAlwaysAutoStart() returns true,
       because the plug-in is whitelisted,

we end up reattach()ing and going to Restarted state, and then going straight
to Playing state in didCreatePlugIn.

Instead, primary plugin promotion should be deferred until after the plugin is created,
so that we can take that one last bit of information (shouldAlwaysAutoStart) into account
before restarting and reattaching the plug-in.

* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement):
(WebCore::HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn):
(WebCore::HTMLPlugInImageElement::restartSnapshottedPlugIn):
(WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn):
(WebCore::HTMLPlugInImageElement::subframeLoaderDidCreatePlugIn):
* html/HTMLPlugInImageElement.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (148559 => 148560)


--- trunk/Source/WebCore/ChangeLog	2013-04-16 22:52:37 UTC (rev 148559)
+++ trunk/Source/WebCore/ChangeLog	2013-04-16 22:58:03 UTC (rev 148560)
@@ -1,3 +1,34 @@
+2013-04-16  Tim Horton  <[email protected]>
+
+        PlugIn Snapshotting: Crashes refreshing non-main-frame PDFPlugins
+        https://bugs.webkit.org/show_bug.cgi?id=114702
+        <rdar://problem/13542020>
+
+        Reviewed by Dean Jackson.
+
+        If:
+
+            a) a plugin fails all the tests in willCreatePlugIn, so it is WaitingForSnapshot there
+            b) primary plugin detection attempts to restart a plugin between the
+               time that willCreatePlugIn and didCreatePlugIn fire
+            c) when didCreatePlugIn fires, shouldAlwaysAutoStart() returns true,
+               because the plug-in is whitelisted,
+
+        we end up reattach()ing and going to Restarted state, and then going straight
+        to Playing state in didCreatePlugIn.
+
+        Instead, primary plugin promotion should be deferred until after the plugin is created,
+        so that we can take that one last bit of information (shouldAlwaysAutoStart) into account
+        before restarting and reattaching the plug-in.
+
+        * html/HTMLPlugInImageElement.cpp:
+        (WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement):
+        (WebCore::HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn):
+        (WebCore::HTMLPlugInImageElement::restartSnapshottedPlugIn):
+        (WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn):
+        (WebCore::HTMLPlugInImageElement::subframeLoaderDidCreatePlugIn):
+        * html/HTMLPlugInImageElement.h:
+
 2013-04-16  Wei James  <[email protected]>
 
         ASSERTION FAILED: i < size(), UNKNOWN in WebCore::ChannelMergerNode::process

Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp (148559 => 148560)


--- trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp	2013-04-16 22:52:37 UTC (rev 148559)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp	2013-04-16 22:58:03 UTC (rev 148560)
@@ -83,6 +83,8 @@
     , m_createdDuringUserGesture(ScriptController::processingUserGesture())
     , m_isRestartedPlugin(false)
     , m_needsCheckForSizeChange(false)
+    , m_plugInWasCreated(false)
+    , m_deferredPromotionToPrimaryPlugIn(false)
     , m_snapshotDecision(SnapshotNotYetDecided)
 {
     setHasCustomStyleCallbacks();
@@ -507,17 +509,23 @@
         return;
 
     if (isPrimarySnapshottedPlugIn) {
-        LOG(Plugins, "%p Plug-in was detected as the primary element in the page. Restart.", this);
-        restartSnapshottedPlugIn();
-        restartSimilarPlugIns();
+        if (m_plugInWasCreated) {
+            LOG(Plugins, "%p Plug-in was detected as the primary element in the page. Restart.", this);
+            restartSnapshottedPlugIn();
+            restartSimilarPlugIns();
+        } else {
+            LOG(Plugins, "%p Plug-in was detected as the primary element in the page, but is not yet created. Will restart later.", this);
+            m_deferredPromotionToPrimaryPlugIn = true;
+        }
     }
 }
 
 void HTMLPlugInImageElement::restartSnapshottedPlugIn()
 {
-    if (displayState() != RestartingWithPendingMouseClick)
-        setDisplayState(Restarting);
+    if (displayState() >= RestartingWithPendingMouseClick)
+        return;
 
+    setDisplayState(Restarting);
     reattach();
 }
 
@@ -578,6 +586,8 @@
     LOG(Plugins, "   Loaded URL: %s", url.string().utf8().data());
 
     m_loadedUrl = url;
+    m_plugInWasCreated = false;
+    m_deferredPromotionToPrimaryPlugIn = false;
 
     if (!document()->page() || !document()->page()->settings()->plugInSnapshottingEnabled()) {
         m_snapshotDecision = NeverSnapshot;
@@ -601,7 +611,7 @@
         LOG(Plugins, "%p Plug-in is blessed, allow it to start", this);
         return;
     }
-    
+
     bool inMainFrame = document()->frame() == document()->page()->mainFrame();
 
     if (document()->isPluginDocument() && inMainFrame) {
@@ -680,12 +690,20 @@
 
 void HTMLPlugInImageElement::subframeLoaderDidCreatePlugIn(const Widget* widget)
 {
-    if (!widget->isPluginViewBase() || !toPluginViewBase(widget)->shouldAlwaysAutoStart())
+    m_plugInWasCreated = true;
+
+    if (widget->isPluginViewBase() && toPluginViewBase(widget)->shouldAlwaysAutoStart()) {
+        LOG(Plugins, "%p Plug-in should auto-start, set to play", this);
+        m_snapshotDecision = NeverSnapshot;
+        setDisplayState(Playing);
         return;
+    }
 
-    LOG(Plugins, "%p Plug-in should auto-start, set to play", this);
-    m_snapshotDecision = NeverSnapshot;
-    setDisplayState(Playing);
+    if (m_deferredPromotionToPrimaryPlugIn) {
+        LOG(Plugins, "%p Plug-in was created, previously deferred promotion to primary. Will promote", this);
+        setIsPrimarySnapshottedPlugIn(true);
+        m_deferredPromotionToPrimaryPlugIn = false;
+    }
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.h (148559 => 148560)


--- trunk/Source/WebCore/html/HTMLPlugInImageElement.h	2013-04-16 22:52:37 UTC (rev 148559)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.h	2013-04-16 22:58:03 UTC (rev 148560)
@@ -160,6 +160,8 @@
     bool m_createdDuringUserGesture;
     bool m_isRestartedPlugin;
     bool m_needsCheckForSizeChange;
+    bool m_plugInWasCreated;
+    bool m_deferredPromotionToPrimaryPlugIn;
     IntSize m_sizeWhenSnapshotted;
     SnapshotDecision m_snapshotDecision;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to