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