blob: 4b249a0221bc4f21d0e9e75eeaf53ad337910ed1 [file] [log] [blame]
[email protected]b62084b2012-06-12 01:53:301// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]cefa749d2011-08-11 22:21:482// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:526#include "base/files/file_path.h"
[email protected]f74c62c2011-10-19 23:34:167#include "base/path_service.h"
[email protected]112158af2013-06-07 23:46:188#include "base/strings/utf_string_conversions.h"
[email protected]cefa749d2011-08-11 22:21:489#include "chrome/browser/extensions/crx_installer.h"
10#include "chrome/browser/extensions/extension_browsertest.h"
11#include "chrome/browser/extensions/extension_service.h"
lukaszab3a950f2017-06-19 21:08:2312#include "chrome/browser/extensions/test_extension_dir.h"
[email protected]cefa749d2011-08-11 22:21:4813#include "chrome/browser/profiles/profile.h"
14#include "chrome/browser/ui/browser.h"
[email protected]47ae23372013-01-29 01:50:4815#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]f74c62c2011-10-19 23:34:1616#include "chrome/common/chrome_paths.h"
[email protected]cefa749d2011-08-11 22:21:4817#include "chrome/common/chrome_switches.h"
[email protected]cefa749d2011-08-11 22:21:4818#include "chrome/test/base/ui_test_utils.h"
brettwb1fc1b82016-02-02 00:19:0819#include "components/prefs/pref_service.h"
[email protected]e67385f2011-12-21 06:00:5620#include "content/public/browser/plugin_service.h"
lukaszab3a950f2017-06-19 21:08:2321#include "content/public/browser/render_frame_host.h"
[email protected]4ca15302012-01-03 05:53:2022#include "content/public/browser/web_contents.h"
[email protected]d7bd3e52013-07-21 04:29:2023#include "content/public/common/webplugininfo.h"
[email protected]7d478cb2012-07-24 17:19:4224#include "content/public/test/browser_test_utils.h"
[email protected]59b0e602014-01-30 00:41:2425#include "extensions/browser/extension_system.h"
[email protected]f2cb3cf2013-03-21 01:40:5326#include "net/dns/mock_host_resolver.h"
svaldeza01f7d92015-11-18 17:47:5627#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]e67385f2011-12-21 06:00:5628
29using content::PluginService;
[email protected]4ca15302012-01-03 05:53:2030using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3431using extensions::Extension;
[email protected]1d5e58b2013-01-31 08:41:4032using extensions::Manifest;
[email protected]cefa749d2011-08-11 22:21:4833
34namespace {
35
thestig4b36dd32014-10-31 20:30:1936const char kExtensionId[] = "bjjcibdiodkkeanflmiijlcfieiemced";
[email protected]cefa749d2011-08-11 22:21:4837
38// This class tests that the Native Client plugin is blocked unless the
39// .nexe is part of an extension from the Chrome Webstore.
40class NaClExtensionTest : public ExtensionBrowserTest {
41 public:
[email protected]90ca44272012-07-18 18:15:4842 NaClExtensionTest() {}
[email protected]cefa749d2011-08-11 22:21:4843
jambb11ed742017-05-01 17:27:5944 void SetUpOnMainThread() override {
45 ExtensionBrowserTest::SetUpOnMainThread();
46 host_resolver()->AddRule("*", "127.0.0.1");
47 ASSERT_TRUE(embedded_test_server()->Start());
48 }
49
[email protected]cefa749d2011-08-11 22:21:4850 protected:
51 enum InstallType {
52 INSTALL_TYPE_COMPONENT,
[email protected]a9d1a1032011-08-18 00:34:5753 INSTALL_TYPE_UNPACKED,
[email protected]cefa749d2011-08-11 22:21:4854 INSTALL_TYPE_FROM_WEBSTORE,
55 INSTALL_TYPE_NON_WEBSTORE,
56 };
[email protected]24a6ccb2013-05-04 00:19:0057 enum PluginType {
58 PLUGIN_TYPE_NONE = 0,
59 PLUGIN_TYPE_EMBED = 1,
60 PLUGIN_TYPE_CONTENT_HANDLER = 2,
61 PLUGIN_TYPE_ALL = PLUGIN_TYPE_EMBED |
62 PLUGIN_TYPE_CONTENT_HANDLER,
63 };
64
[email protected]cefa749d2011-08-11 22:21:4865
[email protected]3aacd9482013-03-19 09:49:3666 const Extension* InstallExtension(const base::FilePath& file_path,
67 InstallType install_type) {
[email protected]06bdd2b2012-11-30 18:47:1368 ExtensionService* service = extensions::ExtensionSystem::Get(
69 browser()->profile())->extension_service();
[email protected]cefa749d2011-08-11 22:21:4870 const Extension* extension = NULL;
71 switch (install_type) {
72 case INSTALL_TYPE_COMPONENT:
73 if (LoadExtensionAsComponent(file_path)) {
74 extension = service->GetExtensionById(kExtensionId, false);
75 }
76 break;
77
[email protected]a9d1a1032011-08-18 00:34:5778 case INSTALL_TYPE_UNPACKED:
79 // Install the extension from a folder so it's unpacked.
80 if (LoadExtension(file_path)) {
81 extension = service->GetExtensionById(kExtensionId, false);
82 }
83 break;
84
[email protected]cefa749d2011-08-11 22:21:4885 case INSTALL_TYPE_FROM_WEBSTORE:
[email protected]a9d1a1032011-08-18 00:34:5786 // Install native_client.crx from the webstore.
[email protected]cefa749d2011-08-11 22:21:4887 if (InstallExtensionFromWebstore(file_path, 1)) {
[email protected]918c2712013-10-21 23:59:5688 extension = service->GetExtensionById(last_loaded_extension_id(),
[email protected]cefa749d2011-08-11 22:21:4889 false);
90 }
91 break;
92
93 case INSTALL_TYPE_NON_WEBSTORE:
[email protected]a9d1a1032011-08-18 00:34:5794 // Install native_client.crx but not from the webstore.
[email protected]cefa749d2011-08-11 22:21:4895 if (ExtensionBrowserTest::InstallExtension(file_path, 1)) {
[email protected]918c2712013-10-21 23:59:5696 extension = service->GetExtensionById(last_loaded_extension_id(),
[email protected]cefa749d2011-08-11 22:21:4897 false);
98 }
99 break;
100 }
101 return extension;
102 }
103
[email protected]3aacd9482013-03-19 09:49:36104 const Extension* InstallExtension(InstallType install_type) {
105 base::FilePath file_path = test_data_dir_.AppendASCII("native_client");
106 return InstallExtension(file_path, install_type);
107 }
108
109 const Extension* InstallHostedApp() {
110 base::FilePath file_path = test_data_dir_.AppendASCII(
111 "native_client_hosted_app");
112 return InstallExtension(file_path, INSTALL_TYPE_FROM_WEBSTORE);
113 }
114
[email protected]f74c62c2011-10-19 23:34:16115 bool IsNaClPluginLoaded() {
[email protected]650b2d52013-02-10 03:41:45116 base::FilePath path;
[email protected]f74c62c2011-10-19 23:34:16117 if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) {
[email protected]d7bd3e52013-07-21 04:29:20118 content::WebPluginInfo info;
[email protected]f74c62c2011-10-19 23:34:16119 return PluginService::GetInstance()->GetPluginInfoByPath(path, &info);
120 }
121 return false;
122 }
123
[email protected]24a6ccb2013-05-04 00:19:00124 void CheckPluginsCreated(const GURL& url, PluginType expected_to_succeed) {
[email protected]e3cb4522013-03-07 22:18:45125 ui_test_utils::NavigateToURL(browser(), url);
[email protected]f74c62c2011-10-19 23:34:16126 // Don't run tests if the NaCl plugin isn't loaded.
127 if (!IsNaClPluginLoaded())
128 return;
129
[email protected]cefa749d2011-08-11 22:21:48130 bool embedded_plugin_created = false;
131 bool content_handler_plugin_created = false;
[email protected]47ae23372013-01-29 01:50:48132 WebContents* web_contents =
133 browser()->tab_strip_model()->GetActiveWebContents();
[email protected]b6987e02013-01-04 18:30:43134 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
135 web_contents,
[email protected]06bc5d92013-01-02 22:44:13136 "window.domAutomationController.send(EmbeddedPluginCreated());",
[email protected]cefa749d2011-08-11 22:21:48137 &embedded_plugin_created));
[email protected]b6987e02013-01-04 18:30:43138 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
139 web_contents,
[email protected]06bc5d92013-01-02 22:44:13140 "window.domAutomationController.send(ContentHandlerPluginCreated());",
[email protected]cefa749d2011-08-11 22:21:48141 &content_handler_plugin_created));
142
[email protected]24a6ccb2013-05-04 00:19:00143 EXPECT_EQ(embedded_plugin_created,
144 (expected_to_succeed & PLUGIN_TYPE_EMBED) != 0);
145 EXPECT_EQ(content_handler_plugin_created,
146 (expected_to_succeed & PLUGIN_TYPE_CONTENT_HANDLER) != 0);
[email protected]cefa749d2011-08-11 22:21:48147 }
[email protected]e3cb4522013-03-07 22:18:45148
[email protected]24a6ccb2013-05-04 00:19:00149 void CheckPluginsCreated(const Extension* extension,
150 PluginType expected_to_succeed) {
151 CheckPluginsCreated(extension->GetResourceURL("test.html"),
152 expected_to_succeed);
[email protected]e3cb4522013-03-07 22:18:45153 }
[email protected]cefa749d2011-08-11 22:21:48154};
155
156// Test that the NaCl plugin isn't blocked for Webstore extensions.
[email protected]7070a872013-11-21 21:23:42157// Disabled: http://crbug.com/319892
158IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_WebStoreExtension) {
[email protected]cefa749d2011-08-11 22:21:48159 const Extension* extension = InstallExtension(INSTALL_TYPE_FROM_WEBSTORE);
160 ASSERT_TRUE(extension);
[email protected]24a6ccb2013-05-04 00:19:00161 CheckPluginsCreated(extension, PLUGIN_TYPE_ALL);
[email protected]cefa749d2011-08-11 22:21:48162}
163
164// Test that the NaCl plugin is blocked for non-Webstore extensions.
[email protected]7070a872013-11-21 21:23:42165// Disabled: http://crbug.com/319892
166IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_NonWebStoreExtension) {
[email protected]cefa749d2011-08-11 22:21:48167 const Extension* extension = InstallExtension(INSTALL_TYPE_NON_WEBSTORE);
168 ASSERT_TRUE(extension);
[email protected]24a6ccb2013-05-04 00:19:00169 CheckPluginsCreated(extension, PLUGIN_TYPE_NONE);
[email protected]cefa749d2011-08-11 22:21:48170}
171
172// Test that the NaCl plugin isn't blocked for component extensions.
[email protected]7070a872013-11-21 21:23:42173// Disabled: http://crbug.com/319892
174IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_ComponentExtension) {
[email protected]cefa749d2011-08-11 22:21:48175 const Extension* extension = InstallExtension(INSTALL_TYPE_COMPONENT);
176 ASSERT_TRUE(extension);
[email protected]1d5e58b2013-01-31 08:41:40177 ASSERT_EQ(extension->location(), Manifest::COMPONENT);
[email protected]24a6ccb2013-05-04 00:19:00178 CheckPluginsCreated(extension, PLUGIN_TYPE_ALL);
[email protected]a9d1a1032011-08-18 00:34:57179}
180
181// Test that the NaCl plugin isn't blocked for unpacked extensions.
[email protected]7070a872013-11-21 21:23:42182// Disabled: http://crbug.com/319892
183IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_UnpackedExtension) {
[email protected]a9d1a1032011-08-18 00:34:57184 const Extension* extension = InstallExtension(INSTALL_TYPE_UNPACKED);
185 ASSERT_TRUE(extension);
[email protected]12075d12013-02-27 05:38:05186 ASSERT_EQ(extension->location(), Manifest::UNPACKED);
[email protected]24a6ccb2013-05-04 00:19:00187 CheckPluginsCreated(extension, PLUGIN_TYPE_ALL);
[email protected]cefa749d2011-08-11 22:21:48188}
189
[email protected]24a6ccb2013-05-04 00:19:00190// Test that the NaCl plugin is blocked for non chrome-extension urls, except
191// if it's a content (MIME type) handler.
[email protected]7070a872013-11-21 21:23:42192// Disabled: http://crbug.com/319892
193IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_NonExtensionScheme) {
[email protected]e3cb4522013-03-07 22:18:45194 const Extension* extension = InstallExtension(INSTALL_TYPE_FROM_WEBSTORE);
195 ASSERT_TRUE(extension);
196 CheckPluginsCreated(
svaldeza01f7d92015-11-18 17:47:56197 embedded_test_server()->GetURL("/extensions/native_client/test.html"),
[email protected]24a6ccb2013-05-04 00:19:00198 PLUGIN_TYPE_CONTENT_HANDLER);
[email protected]e3cb4522013-03-07 22:18:45199}
200
[email protected]3aacd9482013-03-19 09:49:36201// Test that NaCl plugin isn't blocked for hosted app URLs.
202IN_PROC_BROWSER_TEST_F(NaClExtensionTest, HostedApp) {
svaldeza01f7d92015-11-18 17:47:56203 GURL url =
204 embedded_test_server()->GetURL("/extensions/native_client/test.html");
[email protected]3aacd9482013-03-19 09:49:36205 GURL::Replacements replace_host;
mgiuca77752c32015-02-05 07:31:18206 replace_host.SetHostStr("localhost");
[email protected]3aacd9482013-03-19 09:49:36207 replace_host.ClearPort();
208 url = url.ReplaceComponents(replace_host);
209
210 const Extension* extension = InstallHostedApp();
211 ASSERT_TRUE(extension);
[email protected]24a6ccb2013-05-04 00:19:00212 CheckPluginsCreated(url, PLUGIN_TYPE_ALL);
[email protected]3aacd9482013-03-19 09:49:36213}
214
lukaszab3a950f2017-06-19 21:08:23215// Verify that there is no renderer crash when PNaCl plugin is loaded in a
216// subframe with a remote parent / main frame. This is a regression test
217// for https://crbug.com/728295.
218IN_PROC_BROWSER_TEST_F(NaClExtensionTest, MainFrameIsRemote) {
219 // The test tries to load a PNaCl plugin into an *extension* frame to avoid
220 // running into the following error: "Only unpacked extensions and apps
221 // installed from the Chrome Web Store can load NaCl modules without enabling
222 // Native Client in about:flags."
223 extensions::TestExtensionDir ext_dir;
224 ext_dir.WriteFile(FILE_PATH_LITERAL("subframe.html"),
225 "<html><body>Extension frame</body></html>");
226 ext_dir.WriteManifest(
227 R"(
228 {
229 "name": "ChromeSitePerProcessTest.MainFrameIsRemote",
230 "version": "0.1",
231 "manifest_version": 2,
232 "web_accessible_resources": [ "subframe.html" ]
233 }
234 )");
235 const extensions::Extension* extension =
236 LoadExtension(ext_dir.UnpackedPath());
237
238 // Navigate to a page with an iframe.
239 GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
240 ui_test_utils::NavigateToURL(browser(), main_url);
241
242 // Navigate the subframe to the extension's html file.
243 content::WebContents* web_contents =
244 browser()->tab_strip_model()->GetActiveWebContents();
245 ASSERT_TRUE(content::NavigateIframeToURL(
246 web_contents, "test", extension->GetResourceURL("subframe.html")));
247
248 // Sanity check - the test setup should cause main frame and subframe to be in
249 // a different process.
250 content::RenderFrameHost* subframe = web_contents->GetAllFrames()[1];
251 EXPECT_NE(web_contents->GetMainFrame()->GetProcess(), subframe->GetProcess());
252
253 // Insert a plugin element into the subframe. Before the fix from
254 // https://crrev.com/2932703005 this would have trigerred a crash reported in
255 // https://crbug.com/728295.
256 std::string script = R"(
257 var embed = document.createElement("embed");
258 embed.id = "test_nexe";
259 embed.name = "nacl_module";
260 embed.type = "application/x-pnacl";
261 embed.src = "doesnt-exist.nmf";
262 embed.addEventListener('error', function() {
263 window.domAutomationController.send(true);
264 });
265 document.body.appendChild(embed); )";
266 bool done;
267 EXPECT_TRUE(ExecuteScriptAndExtractBool(subframe, script, &done));
268
269 // If we get here, then it means that the renderer didn't crash (the crash
270 // would have prevented the "error" event from firing and so
271 // ExecuteScriptAndExtractBool above wouldn't return).
272}
273
[email protected]cefa749d2011-08-11 22:21:48274} // namespace