summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/content_settings/content_settings_browsertest.cc20
-rw-r--r--chrome/renderer/plugins/plugin_placeholder.cc12
-rw-r--r--chrome/test/data/plugin_delete_self_at_load.html18
3 files changed, 49 insertions, 1 deletions
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index ce32300..30dce25 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -412,4 +412,24 @@ IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, NoCallbackAtLoad) {
EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}
+IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, DeleteSelfAtLoad) {
+ browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
+
+ GURL url = ui_test_utils::GetTestUrl(
+ FilePath(), FilePath().AppendASCII("plugin_delete_self_at_load.html"));
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ string16 expected_title(ASCIIToUTF16("OK"));
+ content::TitleWatcher title_watcher(
+ chrome::GetActiveWebContents(browser()), expected_title);
+
+ content::RenderViewHost* host =
+ chrome::GetActiveWebContents(browser())->GetRenderViewHost();
+ host->Send(new ChromeViewMsg_LoadBlockedPlugins(
+ host->GetRoutingID(), std::string()));
+
+ EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+}
+
#endif // !defined(USE_AURA)
diff --git a/chrome/renderer/plugins/plugin_placeholder.cc b/chrome/renderer/plugins/plugin_placeholder.cc
index 8fe9a52..bce80a8 100644
--- a/chrome/renderer/plugins/plugin_placeholder.cc
+++ b/chrome/renderer/plugins/plugin_placeholder.cc
@@ -323,15 +323,25 @@ void PluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
return;
}
- // Set the new plug-in on the container before initializing it.
WebPluginContainer* container = plugin_->container();
+ // Set the new plug-in on the container before initializing it.
container->setPlugin(new_plugin);
+ // Save the element in case the plug-in is removed from the page during
+ // initialization.
+ WebElement element = container->element();
if (!new_plugin->initialize(container)) {
// We couldn't initialize the new plug-in. Restore the old one and abort.
container->setPlugin(plugin_);
return;
}
+ // The plug-in has been removed from the page. Destroy the old plug-in
+ // (which will destroy us).
+ if (element.parentNode().isNull()) {
+ plugin_->destroy();
+ return;
+ }
+
// During initialization, the new plug-in might have replaced itself in turn
// with another plug-in. Make sure not to use the passed in |new_plugin| after
// this point.
diff --git a/chrome/test/data/plugin_delete_self_at_load.html b/chrome/test/data/plugin_delete_self_at_load.html
new file mode 100644
index 0000000..50805a2
--- /dev/null
+++ b/chrome/test/data/plugin_delete_self_at_load.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+<script>
+function PluginCreated() {
+ document.body.innerHTML = '';
+ document.title = "OK";
+}
+</script>
+</head>
+<body>
+<embed type="application/vnd.npapi-test"
+ src="foo"
+ name="invoke_js_function_on_create"
+ id="plugin"
+ mode="np_embed">
+</embed>
+</body>
+</html>