diff options
-rw-r--r-- | chrome/browser/content_settings/content_settings_browsertest.cc | 20 | ||||
-rw-r--r-- | chrome/renderer/plugins/plugin_placeholder.cc | 12 | ||||
-rw-r--r-- | chrome/test/data/plugin_delete_self_at_load.html | 18 |
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> |