Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / chrome_content_renderer_client_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/renderer/chrome_content_renderer_client.h"
6
7 #include <vector>
8
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/renderer/searchbox/search_bouncer.h"
11 #include "content/public/common/webplugininfo.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "url/gurl.h"
14
15 #if defined(ENABLE_EXTENSIONS)
16 #include "extensions/common/extension.h"
17 #include "extensions/common/extension_builder.h"
18 #include "extensions/common/manifest_constants.h"
19 #endif
20
21 #if !defined(DISABLE_NACL)
22 #include "third_party/WebKit/public/platform/WebString.h"
23 #include "third_party/WebKit/public/platform/WebVector.h"
24 #include "third_party/WebKit/public/web/WebPluginParams.h"
25 #endif
26
27 #if !defined(DISABLE_NACL)
28 using blink::WebPluginParams;
29 using blink::WebString;
30 using blink::WebVector;
31 #endif
32
33 using content::WebPluginInfo;
34 using content::WebPluginMimeType;
35
36 namespace {
37
38 #if !defined(DISABLE_NACL)
39 const bool kNaClRestricted = false;
40 const bool kNaClUnrestricted = true;
41 const bool kExtensionRestricted = false;
42 const bool kExtensionUnrestricted = true;
43 const bool kExtensionNotFromWebStore = false;
44 const bool kExtensionFromWebStore = true;
45 #endif
46
47 #if defined(ENABLE_EXTENSIONS)
48 const bool kNotHostedApp = false;
49 const bool kHostedApp = true;
50 #endif
51
52 #if !defined(DISABLE_NACL)
53 const char kExtensionUrl[] = "chrome-extension://extension_id/background.html";
54
55 const char kPhotosAppURL1[] = "https://foo.plus.google.com";
56 const char kPhotosAppURL2[] = "https://foo.plus.sandbox.google.com";
57 const char kPhotosManifestURL1[] = "https://ssl.gstatic.com/s2/oz/nacl/foo";
58 const char kPhotosManifestURL2[] = "https://ssl.gstatic.com/photos/nacl/foo";
59 const char kChatManifestFS1[] =
60   "filesystem:https://foo.talkgadget.google.com/foo";
61 const char kChatManifestFS2[] = "filesystem:https://foo.plus.google.com/foo";
62 const char kChatManifestFS3[] =
63   "filesystem:https://foo.plus.sandbox.google.com/foo";
64 #endif
65
66 const char kChatAppURL1[] = "https://foo.talkgadget.google.com/hangouts/foo";
67 const char kChatAppURL2[] = "https://foo.plus.google.com/hangouts/foo";
68 const char kChatAppURL3[] = "https://foo.plus.sandbox.google.com/hangouts/foo";
69
70 #if !defined(DISABLE_NACL)
71 bool AllowsDevInterfaces(const WebPluginParams& params) {
72   for (size_t i = 0; i < params.attributeNames.size(); ++i) {
73     if (params.attributeNames[i] == WebString::fromUTF8("@dev"))
74       return true;
75   }
76   return false;
77 }
78
79 void AddFakeDevAttribute(WebPluginParams* params) {
80   WebVector<WebString> names(static_cast<size_t>(1));
81   WebVector<WebString> values(static_cast<size_t>(1));
82   names[0] = WebString::fromUTF8("@dev");
83   values[0] = WebString();
84   params->attributeNames.swap(names);
85   params->attributeValues.swap(values);
86 }
87 #endif
88
89 void AddContentTypeHandler(content::WebPluginInfo* info,
90                            const char* mime_type,
91                            const char* manifest_url) {
92   content::WebPluginMimeType mime_type_info;
93   mime_type_info.mime_type = mime_type;
94   mime_type_info.additional_param_names.push_back(base::UTF8ToUTF16("nacl"));
95   mime_type_info.additional_param_values.push_back(
96       base::UTF8ToUTF16(manifest_url));
97   info->mime_types.push_back(mime_type_info);
98 }
99
100 }  // namespace
101
102 typedef testing::Test ChromeContentRendererClientTest;
103
104
105 #if defined(ENABLE_EXTENSIONS)
106 scoped_refptr<const extensions::Extension> CreateTestExtension(
107     bool is_unrestricted, bool is_from_webstore, bool is_hosted_app,
108     const std::string& app_url) {
109   extensions::Manifest::Location location = is_unrestricted ?
110       extensions::Manifest::UNPACKED :
111       extensions::Manifest::INTERNAL;
112   int flags = is_from_webstore ?
113       extensions::Extension::FROM_WEBSTORE:
114       extensions::Extension::NO_FLAGS;
115
116   base::DictionaryValue manifest;
117   manifest.SetString("name", "NaCl Extension");
118   manifest.SetString("version", "1");
119   manifest.SetInteger("manifest_version", 2);
120   if (is_hosted_app) {
121     base::ListValue* url_list = new base::ListValue();
122     url_list->Append(new base::StringValue(app_url));
123     manifest.Set(extensions::manifest_keys::kWebURLs, url_list);
124     manifest.SetString(extensions::manifest_keys::kLaunchWebURL, app_url);
125   }
126   std::string error;
127   return extensions::Extension::Create(base::FilePath(), location, manifest,
128                                        flags, &error);
129 }
130
131 scoped_refptr<const extensions::Extension> CreateExtension(
132     bool is_unrestricted, bool is_from_webstore) {
133   return CreateTestExtension(
134       is_unrestricted, is_from_webstore, kNotHostedApp, std::string());
135 }
136
137 scoped_refptr<const extensions::Extension> CreateHostedApp(
138     bool is_unrestricted, bool is_from_webstore, const std::string& app_url) {
139   return CreateTestExtension(is_unrestricted, is_from_webstore, kHostedApp,
140                              app_url);
141 }
142 #endif  // defined(ENABLE_EXTENSIONS)
143
144 TEST_F(ChromeContentRendererClientTest, NaClRestriction) {
145   // Unknown content types have no NaCl module.
146   {
147     WebPluginInfo info;
148     EXPECT_EQ(GURL(),
149               ChromeContentRendererClient::GetNaClContentHandlerURL(
150                   "application/x-foo", info));
151   }
152   // Known content types have a NaCl module.
153   {
154     WebPluginInfo info;
155     AddContentTypeHandler(&info, "application/x-foo", "www.foo.com");
156     EXPECT_EQ(GURL("www.foo.com"),
157               ChromeContentRendererClient::GetNaClContentHandlerURL(
158                   "application/x-foo", info));
159   }
160 #if !defined(DISABLE_NACL)
161   // --enable-nacl allows all NaCl apps, with 'dev' interfaces.
162   {
163     WebPluginParams params;
164     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
165         GURL(),
166         GURL(),
167         kNaClUnrestricted,
168         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
169         &params));
170     EXPECT_TRUE(AllowsDevInterfaces(params));
171   }
172   // Unrestricted extensions are allowed without --enable-nacl, with 'dev'
173   // interfaces if called from an extension url.
174   {
175     WebPluginParams params;
176     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
177         GURL(),
178         GURL(kExtensionUrl),
179         kNaClRestricted,
180         CreateExtension(kExtensionUnrestricted, kExtensionNotFromWebStore)
181             .get(),
182         &params));
183     EXPECT_TRUE(AllowsDevInterfaces(params));
184   }
185   // CWS extensions are allowed without --enable-nacl, without 'dev'
186   // interfaces if called from an extension url.
187   {
188     WebPluginParams params;
189     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
190         GURL(),
191         GURL(kExtensionUrl),
192         kNaClRestricted,
193         CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
194         &params));
195     EXPECT_FALSE(AllowsDevInterfaces(params));
196   }
197   // CWS extensions can't get 'dev' interfaces with --enable-nacl.
198   {
199     WebPluginParams params;
200     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
201         GURL(),
202         GURL(kExtensionUrl),
203         kNaClUnrestricted,
204         CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
205         &params));
206     EXPECT_FALSE(AllowsDevInterfaces(params));
207   }
208   // CWS extensions can't get 'dev' interfaces by injecting a fake
209   // '@dev' attribute.
210   {
211     WebPluginParams params;
212     AddFakeDevAttribute(&params);
213     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
214         GURL(),
215         GURL(kExtensionUrl),
216         kNaClRestricted,
217         CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
218         &params));
219     EXPECT_FALSE(AllowsDevInterfaces(params));
220   }
221   // The NaCl PDF extension is allowed without --enable-nacl, with 'dev'
222   // interfaces, from all URLs.
223   {
224     WebPluginParams params;
225     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
226         GURL("chrome-extension://acadkphlmlegjaadjagenfimbpphcgnh"),
227         GURL(),
228         kNaClRestricted,
229         CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
230         &params));
231     EXPECT_TRUE(AllowsDevInterfaces(params));
232   }
233   // Whitelisted URLs are allowed without --enable-nacl, without 'dev'
234   // interfaces. There is a whitelist for the app URL and the manifest URL.
235   {
236     WebPluginParams params;
237     // Whitelisted Photos app is allowed (two app URLs, two manifest URLs)
238     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
239         GURL(kPhotosManifestURL1),
240         GURL(kPhotosAppURL1),
241         kNaClRestricted,
242         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
243         &params));
244     EXPECT_FALSE(AllowsDevInterfaces(params));
245     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
246         GURL(kPhotosManifestURL1),
247         GURL(kPhotosAppURL2),
248         kNaClRestricted,
249         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
250         &params));
251     EXPECT_FALSE(AllowsDevInterfaces(params));
252     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
253         GURL(kPhotosManifestURL2),
254         GURL(kPhotosAppURL1),
255         kNaClRestricted,
256         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
257         &params));
258     EXPECT_FALSE(AllowsDevInterfaces(params));
259     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
260         GURL(kPhotosManifestURL2),
261         GURL(kPhotosAppURL2),
262         kNaClRestricted,
263         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
264         &params));
265     EXPECT_FALSE(AllowsDevInterfaces(params));
266     // Whitelisted Chat app is allowed.
267     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
268         GURL(kChatManifestFS1),
269         GURL(kChatAppURL1),
270         kNaClRestricted,
271         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
272         &params));
273     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
274         GURL(kChatManifestFS2),
275         GURL(kChatAppURL2),
276         kNaClRestricted,
277         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
278         &params));
279     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
280         GURL(kChatManifestFS3),
281         GURL(kChatAppURL3),
282         kNaClRestricted,
283         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
284         &params));
285
286     // Whitelisted manifest URL, bad app URLs, NOT allowed.
287     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
288         GURL(kPhotosManifestURL1),
289         GURL("http://plus.google.com/foo"),  // http scheme
290         kNaClRestricted,
291         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
292         &params));
293     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
294         GURL(kPhotosManifestURL1),
295         GURL("http://plus.sandbox.google.com/foo"),  // http scheme
296         kNaClRestricted,
297         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
298         &params));
299     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
300         GURL(kPhotosManifestURL1),
301         GURL("https://plus.google.evil.com/foo"),  // bad host
302         kNaClRestricted,
303         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
304         &params));
305     // Whitelisted app URL, bad manifest URL, NOT allowed.
306     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
307         GURL("http://ssl.gstatic.com/s2/oz/nacl/foo"),  // http scheme
308         GURL(kPhotosAppURL1),
309         kNaClRestricted,
310         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
311         &params));
312     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
313         GURL("https://ssl.gstatic.evil.com/s2/oz/nacl/foo"),  // bad host
314         GURL(kPhotosAppURL1),
315         kNaClRestricted,
316         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
317         &params));
318     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
319         GURL("https://ssl.gstatic.com/wrong/s2/oz/nacl/foo"),  // bad path
320         GURL(kPhotosAppURL1),
321         kNaClRestricted,
322         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
323         &params));
324   }
325   // Whitelisted URLs can't get 'dev' interfaces with --enable-nacl.
326   {
327     WebPluginParams params;
328     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
329         GURL(kPhotosManifestURL1),
330         GURL(kPhotosAppURL1),
331         kNaClUnrestricted,
332         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
333         &params));
334     EXPECT_FALSE(AllowsDevInterfaces(params));
335   }
336   // Whitelisted URLs can't get 'dev' interfaces by injecting a fake
337   // '@dev' attribute.
338   {
339     WebPluginParams params;
340     AddFakeDevAttribute(&params);
341     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
342         GURL(kPhotosManifestURL1),
343         GURL(kPhotosAppURL1),
344         kNaClRestricted,
345         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
346         &params));
347     EXPECT_FALSE(AllowsDevInterfaces(params));
348   }
349   // Non-whitelisted URLs are blocked without --enable-nacl.
350   {
351     WebPluginParams params;
352     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
353         GURL(),
354         GURL("https://plus.google.com.evil.com/foo1"),
355         kNaClRestricted,
356         CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
357         &params));
358     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
359         GURL(),
360         GURL("https://plus.google.com.evil.com/foo2"),
361         kNaClRestricted,
362         CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
363         &params));
364     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
365         GURL(),
366         GURL("https://talkgadget.google.com.evil.com/foo3"),
367         kNaClRestricted,
368         CreateExtension(kExtensionUnrestricted, kExtensionNotFromWebStore)
369             .get(),
370         &params));
371     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
372         GURL(),
373         GURL("https://talkgadget.google.com.evil.com/foo4"),
374         kNaClRestricted,
375         CreateExtension(kExtensionUnrestricted, kExtensionFromWebStore).get(),
376         &params));
377   }
378   // Non chrome-extension:// URLs belonging to hosted apps are allowed.
379   {
380     WebPluginParams params;
381     EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
382         GURL(),
383         GURL("http://example.com/test.html"),
384         kNaClRestricted,
385         CreateHostedApp(kExtensionRestricted,
386                         kExtensionNotFromWebStore,
387                         "http://example.com/").get(),
388         &params));
389     EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
390         GURL(),
391         GURL("http://example.evil.com/test.html"),
392         kNaClRestricted,
393         CreateHostedApp(kExtensionRestricted,
394                         kExtensionNotFromWebStore,
395                         "http://example.com/").get(),
396         &params));
397   }
398 #endif  // !defined(DISABLE_NACL)
399 }
400
401 TEST_F(ChromeContentRendererClientTest, AllowPepperMediaStreamAPI) {
402   ChromeContentRendererClient test;
403 #if !defined(OS_ANDROID)
404   EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL1)));
405   EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL2)));
406   EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL3)));
407 #else
408   EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL1)));
409   EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL2)));
410   EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL3)));
411 #endif
412   EXPECT_FALSE(test.AllowPepperMediaStreamAPI(
413       GURL("http://talkgadget.google.com/hangouts/foo")));
414   EXPECT_FALSE(test.AllowPepperMediaStreamAPI(
415       GURL("https://talkgadget.evil.com/hangouts/foo")));
416 }
417
418 TEST_F(ChromeContentRendererClientTest, ShouldSuppressErrorPage) {
419   ChromeContentRendererClient client;
420   client.search_bouncer_.reset(new SearchBouncer);
421   client.search_bouncer_->OnSetSearchURLs(
422       std::vector<GURL>(), GURL("http://example.com/n"));
423   EXPECT_FALSE(client.ShouldSuppressErrorPage(NULL,
424                                               GURL("http://example.com")));
425   EXPECT_TRUE(client.ShouldSuppressErrorPage(NULL,
426                                              GURL("http://example.com/n")));
427 }