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;
};