Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / extension_unittest.cc
1 // Copyright (c) 2013 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 "base/file_util.h"
6 #include "base/format_macros.h"
7 #include "base/path_service.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/common/chrome_paths.h"
11 #include "chrome/common/extensions/command.h"
12 #include "chrome/common/extensions/extension_test_util.h"
13 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
14 #include "chrome/common/url_constants.h"
15 #include "extensions/common/extension.h"
16 #include "extensions/common/extension_resource.h"
17 #include "extensions/common/file_util.h"
18 #include "extensions/common/manifest.h"
19 #include "extensions/common/permissions/permissions_data.h"
20 #include "net/base/mime_sniffer.h"
21 #include "net/dns/mock_host_resolver.h"
22 #include "skia/ext/image_operations.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/skia/include/core/SkBitmap.h"
25 #include "ui/gfx/codec/png_codec.h"
26 #include "url/gurl.h"
27
28 using extension_test_util::LoadManifest;
29 using extension_test_util::LoadManifestStrict;
30 using base::FilePath;
31
32 namespace extensions {
33
34 // We persist location values in the preferences, so this is a sanity test that
35 // someone doesn't accidentally change them.
36 TEST(ExtensionTest, LocationValuesTest) {
37   ASSERT_EQ(0, Manifest::INVALID_LOCATION);
38   ASSERT_EQ(1, Manifest::INTERNAL);
39   ASSERT_EQ(2, Manifest::EXTERNAL_PREF);
40   ASSERT_EQ(3, Manifest::EXTERNAL_REGISTRY);
41   ASSERT_EQ(4, Manifest::UNPACKED);
42   ASSERT_EQ(5, Manifest::COMPONENT);
43   ASSERT_EQ(6, Manifest::EXTERNAL_PREF_DOWNLOAD);
44   ASSERT_EQ(7, Manifest::EXTERNAL_POLICY_DOWNLOAD);
45   ASSERT_EQ(8, Manifest::COMMAND_LINE);
46   ASSERT_EQ(9, Manifest::EXTERNAL_POLICY);
47 }
48
49 TEST(ExtensionTest, LocationPriorityTest) {
50   for (int i = 0; i < Manifest::NUM_LOCATIONS; i++) {
51     Manifest::Location loc = static_cast<Manifest::Location>(i);
52
53     // INVALID is not a valid location.
54     if (loc == Manifest::INVALID_LOCATION)
55       continue;
56
57     // Comparing a location that has no rank will hit a CHECK. Do a
58     // compare with every valid location, to be sure each one is covered.
59
60     // Check that no install source can override a componenet extension.
61     ASSERT_EQ(Manifest::COMPONENT,
62               Manifest::GetHigherPriorityLocation(Manifest::COMPONENT, loc));
63     ASSERT_EQ(Manifest::COMPONENT,
64               Manifest::GetHigherPriorityLocation(loc, Manifest::COMPONENT));
65
66     // Check that any source can override a user install. This might change
67     // in the future, in which case this test should be updated.
68     ASSERT_EQ(loc,
69               Manifest::GetHigherPriorityLocation(Manifest::INTERNAL, loc));
70     ASSERT_EQ(loc,
71               Manifest::GetHigherPriorityLocation(loc, Manifest::INTERNAL));
72   }
73
74   // Check a few interesting cases that we know can happen:
75   ASSERT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD,
76             Manifest::GetHigherPriorityLocation(
77                 Manifest::EXTERNAL_POLICY_DOWNLOAD,
78                 Manifest::EXTERNAL_PREF));
79
80   ASSERT_EQ(Manifest::EXTERNAL_PREF,
81             Manifest::GetHigherPriorityLocation(
82                 Manifest::INTERNAL,
83                 Manifest::EXTERNAL_PREF));
84 }
85
86 TEST(ExtensionTest, GetResourceURLAndPath) {
87   scoped_refptr<Extension> extension = LoadManifestStrict("empty_manifest",
88       "empty.json");
89   EXPECT_TRUE(extension.get());
90
91   EXPECT_EQ(extension->url().spec() + "bar/baz.js",
92             Extension::GetResourceURL(extension->url(), "bar/baz.js").spec());
93   EXPECT_EQ(extension->url().spec() + "baz.js",
94             Extension::GetResourceURL(extension->url(),
95                                       "bar/../baz.js").spec());
96   EXPECT_EQ(extension->url().spec() + "baz.js",
97             Extension::GetResourceURL(extension->url(), "../baz.js").spec());
98
99   // Test that absolute-looking paths ("/"-prefixed) are pasted correctly.
100   EXPECT_EQ(extension->url().spec() + "test.html",
101             extension->GetResourceURL("/test.html").spec());
102 }
103
104 TEST(ExtensionTest, GetResource) {
105   const FilePath valid_path_test_cases[] = {
106     FilePath(FILE_PATH_LITERAL("manifest.json")),
107     FilePath(FILE_PATH_LITERAL("a/b/c/manifest.json")),
108     FilePath(FILE_PATH_LITERAL("com/manifest.json")),
109     FilePath(FILE_PATH_LITERAL("lpt/manifest.json")),
110   };
111   const FilePath invalid_path_test_cases[] = {
112     // Directory name
113     FilePath(FILE_PATH_LITERAL("src/")),
114     // Contains a drive letter specification.
115     FilePath(FILE_PATH_LITERAL("C:\\manifest.json")),
116     // Use backslash '\\' as separator.
117     FilePath(FILE_PATH_LITERAL("a\\b\\c\\manifest.json")),
118     // Reserved Characters with extension
119     FilePath(FILE_PATH_LITERAL("mani>fest.json")),
120     FilePath(FILE_PATH_LITERAL("mani<fest.json")),
121     FilePath(FILE_PATH_LITERAL("mani*fest.json")),
122     FilePath(FILE_PATH_LITERAL("mani:fest.json")),
123     FilePath(FILE_PATH_LITERAL("mani?fest.json")),
124     FilePath(FILE_PATH_LITERAL("mani|fest.json")),
125     // Reserved Characters without extension
126     FilePath(FILE_PATH_LITERAL("mani>fest")),
127     FilePath(FILE_PATH_LITERAL("mani<fest")),
128     FilePath(FILE_PATH_LITERAL("mani*fest")),
129     FilePath(FILE_PATH_LITERAL("mani:fest")),
130     FilePath(FILE_PATH_LITERAL("mani?fest")),
131     FilePath(FILE_PATH_LITERAL("mani|fest")),
132     // Reserved Names with extension.
133     FilePath(FILE_PATH_LITERAL("com1.json")),
134     FilePath(FILE_PATH_LITERAL("com9.json")),
135     FilePath(FILE_PATH_LITERAL("LPT1.json")),
136     FilePath(FILE_PATH_LITERAL("LPT9.json")),
137     FilePath(FILE_PATH_LITERAL("CON.json")),
138     FilePath(FILE_PATH_LITERAL("PRN.json")),
139     FilePath(FILE_PATH_LITERAL("AUX.json")),
140     FilePath(FILE_PATH_LITERAL("NUL.json")),
141     // Reserved Names without extension.
142     FilePath(FILE_PATH_LITERAL("com1")),
143     FilePath(FILE_PATH_LITERAL("com9")),
144     FilePath(FILE_PATH_LITERAL("LPT1")),
145     FilePath(FILE_PATH_LITERAL("LPT9")),
146     FilePath(FILE_PATH_LITERAL("CON")),
147     FilePath(FILE_PATH_LITERAL("PRN")),
148     FilePath(FILE_PATH_LITERAL("AUX")),
149     FilePath(FILE_PATH_LITERAL("NUL")),
150     // Reserved Names as directory.
151     FilePath(FILE_PATH_LITERAL("com1/manifest.json")),
152     FilePath(FILE_PATH_LITERAL("com9/manifest.json")),
153     FilePath(FILE_PATH_LITERAL("LPT1/manifest.json")),
154     FilePath(FILE_PATH_LITERAL("LPT9/manifest.json")),
155     FilePath(FILE_PATH_LITERAL("CON/manifest.json")),
156     FilePath(FILE_PATH_LITERAL("PRN/manifest.json")),
157     FilePath(FILE_PATH_LITERAL("AUX/manifest.json")),
158     FilePath(FILE_PATH_LITERAL("NUL/manifest.json")),
159   };
160
161   scoped_refptr<Extension> extension = LoadManifestStrict("empty_manifest",
162       "empty.json");
163   EXPECT_TRUE(extension.get());
164   for (size_t i = 0; i < arraysize(valid_path_test_cases); ++i)
165     EXPECT_TRUE(!extension->GetResource(valid_path_test_cases[i]).empty());
166   for (size_t i = 0; i < arraysize(invalid_path_test_cases); ++i)
167     EXPECT_TRUE(extension->GetResource(invalid_path_test_cases[i]).empty());
168 }
169
170 TEST(ExtensionTest, GetAbsolutePathNoError) {
171   scoped_refptr<Extension> extension = LoadManifestStrict("absolute_path",
172       "absolute.json");
173   EXPECT_TRUE(extension.get());
174   std::string err;
175   std::vector<InstallWarning> warnings;
176   EXPECT_TRUE(file_util::ValidateExtension(extension.get(), &err, &warnings));
177   EXPECT_EQ(0U, warnings.size());
178
179   EXPECT_EQ(extension->path().AppendASCII("test.html").value(),
180             extension->GetResource("test.html").GetFilePath().value());
181   EXPECT_EQ(extension->path().AppendASCII("test.js").value(),
182             extension->GetResource("test.js").GetFilePath().value());
183 }
184
185
186 TEST(ExtensionTest, IdIsValid) {
187   EXPECT_TRUE(Extension::IdIsValid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
188   EXPECT_TRUE(Extension::IdIsValid("pppppppppppppppppppppppppppppppp"));
189   EXPECT_TRUE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnop"));
190   EXPECT_TRUE(Extension::IdIsValid("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"));
191   EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno"));
192   EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnopa"));
193   EXPECT_FALSE(Extension::IdIsValid("0123456789abcdef0123456789abcdef"));
194   EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnoq"));
195   EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno0"));
196 }
197
198
199 // This test ensures that the mimetype sniffing code stays in sync with the
200 // actual crx files that we test other parts of the system with.
201 TEST(ExtensionTest, MimeTypeSniffing) {
202   base::FilePath path;
203   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
204   path = path.AppendASCII("extensions").AppendASCII("good.crx");
205
206   std::string data;
207   ASSERT_TRUE(base::ReadFileToString(path, &data));
208
209   std::string result;
210   EXPECT_TRUE(net::SniffMimeType(data.c_str(),
211                                  data.size(),
212                                  GURL("http://www.example.com/foo.crx"),
213                                  std::string(),
214                                  &result));
215   EXPECT_EQ(std::string(Extension::kMimeType), result);
216
217   data.clear();
218   result.clear();
219   path = path.DirName().AppendASCII("bad_magic.crx");
220   ASSERT_TRUE(base::ReadFileToString(path, &data));
221   EXPECT_TRUE(net::SniffMimeType(data.c_str(),
222                                  data.size(),
223                                  GURL("http://www.example.com/foo.crx"),
224                                  std::string(),
225                                  &result));
226   EXPECT_EQ("application/octet-stream", result);
227 }
228
229 TEST(ExtensionTest, WantsFileAccess) {
230   scoped_refptr<Extension> extension;
231   GURL file_url("file:///etc/passwd");
232
233   // Ignore the policy delegate for this test.
234   PermissionsData::SetPolicyDelegate(NULL);
235
236   // <all_urls> permission
237   extension = LoadManifest("permissions", "permissions_all_urls.json");
238   EXPECT_TRUE(extension->wants_file_access());
239   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
240       extension.get(), file_url, file_url, -1, NULL, -1, NULL));
241   extension = LoadManifest(
242       "permissions", "permissions_all_urls.json", Extension::ALLOW_FILE_ACCESS);
243   EXPECT_TRUE(extension->wants_file_access());
244   EXPECT_TRUE(PermissionsData::CanExecuteScriptOnPage(
245       extension.get(), file_url, file_url, -1, NULL, -1, NULL));
246
247   // file:///* permission
248   extension = LoadManifest("permissions", "permissions_file_scheme.json");
249   EXPECT_TRUE(extension->wants_file_access());
250   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
251       extension.get(), file_url, file_url, -1, NULL, -1, NULL));
252   extension = LoadManifest("permissions",
253                            "permissions_file_scheme.json",
254                            Extension::ALLOW_FILE_ACCESS);
255   EXPECT_TRUE(extension->wants_file_access());
256   EXPECT_TRUE(PermissionsData::CanExecuteScriptOnPage(
257       extension.get(), file_url, file_url, -1, NULL, -1, NULL));
258
259   // http://* permission
260   extension = LoadManifest("permissions", "permissions_http_scheme.json");
261   EXPECT_FALSE(extension->wants_file_access());
262   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
263       extension.get(), file_url, file_url, -1, NULL, -1, NULL));
264   extension = LoadManifest("permissions",
265                            "permissions_http_scheme.json",
266                            Extension::ALLOW_FILE_ACCESS);
267   EXPECT_FALSE(extension->wants_file_access());
268   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
269       extension.get(), file_url, file_url, -1, NULL, -1, NULL));
270
271   // <all_urls> content script match
272   extension = LoadManifest("permissions", "content_script_all_urls.json");
273   EXPECT_TRUE(extension->wants_file_access());
274   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
275       extension.get(),
276       file_url,
277       file_url,
278       -1,
279       &ContentScriptsInfo::GetContentScripts(extension.get())[0],
280       -1,
281       NULL));
282   extension = LoadManifest("permissions", "content_script_all_urls.json",
283       Extension::ALLOW_FILE_ACCESS);
284   EXPECT_TRUE(extension->wants_file_access());
285   EXPECT_TRUE(PermissionsData::CanExecuteScriptOnPage(
286       extension.get(),
287       file_url,
288       file_url,
289       -1,
290       &ContentScriptsInfo::GetContentScripts(extension.get())[0],
291       -1,
292       NULL));
293
294   // file:///* content script match
295   extension = LoadManifest("permissions", "content_script_file_scheme.json");
296   EXPECT_TRUE(extension->wants_file_access());
297   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
298       extension.get(),
299       file_url,
300       file_url,
301       -1,
302       &ContentScriptsInfo::GetContentScripts(extension.get())[0],
303       -1,
304       NULL));
305   extension = LoadManifest("permissions", "content_script_file_scheme.json",
306       Extension::ALLOW_FILE_ACCESS);
307   EXPECT_TRUE(extension->wants_file_access());
308   EXPECT_TRUE(PermissionsData::CanExecuteScriptOnPage(
309       extension.get(),
310       file_url,
311       file_url,
312       -1,
313       &ContentScriptsInfo::GetContentScripts(extension.get())[0],
314       -1,
315       NULL));
316
317   // http://* content script match
318   extension = LoadManifest("permissions", "content_script_http_scheme.json");
319   EXPECT_FALSE(extension->wants_file_access());
320   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
321       extension.get(),
322       file_url,
323       file_url,
324       -1,
325       &ContentScriptsInfo::GetContentScripts(extension.get())[0],
326       -1,
327       NULL));
328   extension = LoadManifest("permissions", "content_script_http_scheme.json",
329       Extension::ALLOW_FILE_ACCESS);
330   EXPECT_FALSE(extension->wants_file_access());
331   EXPECT_FALSE(PermissionsData::CanExecuteScriptOnPage(
332       extension.get(),
333       file_url,
334       file_url,
335       -1,
336       &ContentScriptsInfo::GetContentScripts(extension.get())[0],
337       -1,
338       NULL));
339 }
340
341 TEST(ExtensionTest, ExtraFlags) {
342   scoped_refptr<Extension> extension;
343   extension = LoadManifest("app", "manifest.json", Extension::FROM_WEBSTORE);
344   EXPECT_TRUE(extension->from_webstore());
345
346   extension = LoadManifest("app", "manifest.json", Extension::FROM_BOOKMARK);
347   EXPECT_TRUE(extension->from_bookmark());
348
349   extension = LoadManifest("app", "manifest.json", Extension::NO_FLAGS);
350   EXPECT_FALSE(extension->from_bookmark());
351   EXPECT_FALSE(extension->from_webstore());
352 }
353
354 }  // namespace extensions