OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/extensions/extension_file_util.h" | 5 #include "chrome/common/extensions/extension_file_util.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include <set> |
8 #include "base/files/scoped_temp_dir.h" | 8 |
9 #include "base/json/json_string_value_serializer.h" | |
10 #include "base/path_service.h" | 9 #include "base/path_service.h" |
11 #include "base/strings/stringprintf.h" | |
12 #include "base/strings/utf_string_conversions.h" | |
13 #include "chrome/common/chrome_paths.h" | 10 #include "chrome/common/chrome_paths.h" |
14 #include "extensions/common/constants.h" | |
15 #include "extensions/common/extension.h" | 11 #include "extensions/common/extension.h" |
| 12 #include "extensions/common/file_util.h" |
16 #include "extensions/common/manifest.h" | 13 #include "extensions/common/manifest.h" |
17 #include "extensions/common/manifest_constants.h" | |
18 #include "grit/generated_resources.h" | |
19 #include "testing/gmock/include/gmock/gmock.h" | |
20 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
21 #include "ui/base/l10n/l10n_util.h" | |
22 | 15 |
23 using extensions::Extension; | 16 namespace extensions { |
24 using extensions::Manifest; | |
25 | 17 |
26 namespace keys = extensions::manifest_keys; | 18 typedef testing::Test ExtensionFileUtilTest; |
27 | 19 |
28 class ExtensionFileUtilTest : public testing::Test { | 20 // Test that a browser action extension returns a path to an icon. |
29 }; | 21 TEST_F(ExtensionFileUtilTest, GetBrowserImagePaths) { |
30 | |
31 TEST_F(ExtensionFileUtilTest, InstallUninstallGarbageCollect) { | |
32 base::ScopedTempDir temp; | |
33 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
34 | |
35 // Create a source extension. | |
36 std::string extension_id("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); | |
37 std::string version("1.0"); | |
38 base::FilePath src = temp.path().AppendASCII(extension_id); | |
39 ASSERT_TRUE(base::CreateDirectory(src)); | |
40 | |
41 // Create a extensions tree. | |
42 base::FilePath all_extensions = temp.path().AppendASCII("extensions"); | |
43 ASSERT_TRUE(base::CreateDirectory(all_extensions)); | |
44 | |
45 // Install in empty directory. Should create parent directories as needed. | |
46 base::FilePath version_1 = extension_file_util::InstallExtension( | |
47 src, | |
48 extension_id, | |
49 version, | |
50 all_extensions); | |
51 ASSERT_EQ(version_1.value(), | |
52 all_extensions.AppendASCII(extension_id).AppendASCII("1.0_0") | |
53 .value()); | |
54 ASSERT_TRUE(base::DirectoryExists(version_1)); | |
55 | |
56 // Should have moved the source. | |
57 ASSERT_FALSE(base::DirectoryExists(src)); | |
58 | |
59 // Install again. Should create a new one with different name. | |
60 ASSERT_TRUE(base::CreateDirectory(src)); | |
61 base::FilePath version_2 = extension_file_util::InstallExtension( | |
62 src, | |
63 extension_id, | |
64 version, | |
65 all_extensions); | |
66 ASSERT_EQ(version_2.value(), | |
67 all_extensions.AppendASCII(extension_id).AppendASCII("1.0_1") | |
68 .value()); | |
69 ASSERT_TRUE(base::DirectoryExists(version_2)); | |
70 | |
71 // Should have moved the source. | |
72 ASSERT_FALSE(base::DirectoryExists(src)); | |
73 | |
74 // Install yet again. Should create a new one with a different name. | |
75 ASSERT_TRUE(base::CreateDirectory(src)); | |
76 base::FilePath version_3 = extension_file_util::InstallExtension( | |
77 src, | |
78 extension_id, | |
79 version, | |
80 all_extensions); | |
81 ASSERT_EQ(version_3.value(), | |
82 all_extensions.AppendASCII(extension_id).AppendASCII("1.0_2") | |
83 .value()); | |
84 ASSERT_TRUE(base::DirectoryExists(version_3)); | |
85 | |
86 // Uninstall. Should remove entire extension subtree. | |
87 extension_file_util::UninstallExtension(all_extensions, extension_id); | |
88 ASSERT_FALSE(base::DirectoryExists(version_1.DirName())); | |
89 ASSERT_FALSE(base::DirectoryExists(version_2.DirName())); | |
90 ASSERT_FALSE(base::DirectoryExists(version_3.DirName())); | |
91 ASSERT_TRUE(base::DirectoryExists(all_extensions)); | |
92 } | |
93 | |
94 TEST_F(ExtensionFileUtilTest, LoadExtensionWithValidLocales) { | |
95 base::FilePath install_dir; | 22 base::FilePath install_dir; |
96 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | 23 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); |
97 install_dir = install_dir.AppendASCII("extensions") | 24 install_dir = install_dir.AppendASCII("extensions") |
98 .AppendASCII("good") | 25 .AppendASCII("api_test") |
99 .AppendASCII("Extensions") | 26 .AppendASCII("browser_action") |
100 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") | 27 .AppendASCII("basics"); |
101 .AppendASCII("1.0.0.0"); | |
102 | 28 |
103 std::string error; | 29 std::string error; |
104 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | 30 scoped_refptr<Extension> extension(file_util::LoadExtension( |
105 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 31 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
106 ASSERT_TRUE(extension.get() != NULL); | 32 ASSERT_TRUE(extension.get()); |
107 EXPECT_EQ("The first extension that I made.", extension->description()); | 33 |
| 34 // The extension contains one icon. |
| 35 std::set<base::FilePath> paths = |
| 36 extension_file_util::GetBrowserImagePaths(extension.get()); |
| 37 ASSERT_EQ(1u, paths.size()); |
| 38 EXPECT_EQ("icon.png", paths.begin()->BaseName().AsUTF8Unsafe()); |
108 } | 39 } |
109 | 40 |
110 TEST_F(ExtensionFileUtilTest, LoadExtensionWithoutLocalesFolder) { | 41 } // namespace extensions |
111 base::FilePath install_dir; | |
112 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | |
113 install_dir = install_dir.AppendASCII("extensions") | |
114 .AppendASCII("good") | |
115 .AppendASCII("Extensions") | |
116 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa") | |
117 .AppendASCII("1.0"); | |
118 | |
119 std::string error; | |
120 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | |
121 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | |
122 ASSERT_FALSE(extension.get() == NULL); | |
123 EXPECT_TRUE(error.empty()); | |
124 } | |
125 | |
126 TEST_F(ExtensionFileUtilTest, CheckIllegalFilenamesNoUnderscores) { | |
127 base::ScopedTempDir temp; | |
128 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
129 | |
130 base::FilePath src_path = temp.path().AppendASCII("some_dir"); | |
131 ASSERT_TRUE(base::CreateDirectory(src_path)); | |
132 | |
133 std::string data = "{ \"name\": { \"message\": \"foobar\" } }"; | |
134 ASSERT_TRUE(base::WriteFile(src_path.AppendASCII("some_file.txt"), | |
135 data.c_str(), data.length())); | |
136 std::string error; | |
137 EXPECT_TRUE(extension_file_util::CheckForIllegalFilenames(temp.path(), | |
138 &error)); | |
139 } | |
140 | |
141 TEST_F(ExtensionFileUtilTest, CheckIllegalFilenamesOnlyReserved) { | |
142 base::ScopedTempDir temp; | |
143 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
144 | |
145 const base::FilePath::CharType* folders[] = | |
146 { extensions::kLocaleFolder, extensions::kPlatformSpecificFolder }; | |
147 | |
148 for (size_t i = 0; i < arraysize(folders); i++) { | |
149 base::FilePath src_path = temp.path().Append(folders[i]); | |
150 ASSERT_TRUE(base::CreateDirectory(src_path)); | |
151 } | |
152 | |
153 std::string error; | |
154 EXPECT_TRUE(extension_file_util::CheckForIllegalFilenames(temp.path(), | |
155 &error)); | |
156 } | |
157 | |
158 TEST_F(ExtensionFileUtilTest, CheckIllegalFilenamesReservedAndIllegal) { | |
159 base::ScopedTempDir temp; | |
160 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
161 | |
162 base::FilePath src_path = temp.path().Append(extensions::kLocaleFolder); | |
163 ASSERT_TRUE(base::CreateDirectory(src_path)); | |
164 | |
165 src_path = temp.path().AppendASCII("_some_dir"); | |
166 ASSERT_TRUE(base::CreateDirectory(src_path)); | |
167 | |
168 std::string error; | |
169 EXPECT_FALSE(extension_file_util::CheckForIllegalFilenames(temp.path(), | |
170 &error)); | |
171 } | |
172 | |
173 TEST_F(ExtensionFileUtilTest, | |
174 LoadExtensionGivesHelpfullErrorOnMissingManifest) { | |
175 base::FilePath install_dir; | |
176 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | |
177 install_dir = install_dir.AppendASCII("extensions") | |
178 .AppendASCII("bad") | |
179 .AppendASCII("Extensions") | |
180 .AppendASCII("dddddddddddddddddddddddddddddddd") | |
181 .AppendASCII("1.0"); | |
182 | |
183 std::string error; | |
184 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | |
185 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | |
186 ASSERT_TRUE(extension.get() == NULL); | |
187 ASSERT_FALSE(error.empty()); | |
188 ASSERT_STREQ("Manifest file is missing or unreadable.", error.c_str()); | |
189 } | |
190 | |
191 TEST_F(ExtensionFileUtilTest, LoadExtensionGivesHelpfullErrorOnBadManifest) { | |
192 base::FilePath install_dir; | |
193 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | |
194 install_dir = install_dir.AppendASCII("extensions") | |
195 .AppendASCII("bad") | |
196 .AppendASCII("Extensions") | |
197 .AppendASCII("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") | |
198 .AppendASCII("1.0"); | |
199 | |
200 std::string error; | |
201 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | |
202 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | |
203 ASSERT_TRUE(extension.get() == NULL); | |
204 ASSERT_FALSE(error.empty()); | |
205 ASSERT_STREQ("Manifest is not valid JSON. " | |
206 "Line: 2, column: 16, Syntax error.", error.c_str()); | |
207 } | |
208 | |
209 TEST_F(ExtensionFileUtilTest, FailLoadingNonUTF8Scripts) { | |
210 base::FilePath install_dir; | |
211 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | |
212 install_dir = install_dir.AppendASCII("extensions") | |
213 .AppendASCII("bad") | |
214 .AppendASCII("bad_encoding"); | |
215 | |
216 std::string error; | |
217 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | |
218 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | |
219 ASSERT_TRUE(extension.get() == NULL); | |
220 ASSERT_STREQ("Could not load file 'bad_encoding.js' for content script. " | |
221 "It isn't UTF-8 encoded.", | |
222 error.c_str()); | |
223 } | |
224 | |
225 static scoped_refptr<Extension> LoadExtensionManifest( | |
226 base::DictionaryValue* manifest, | |
227 const base::FilePath& manifest_dir, | |
228 Manifest::Location location, | |
229 int extra_flags, | |
230 std::string* error) { | |
231 scoped_refptr<Extension> extension = Extension::Create( | |
232 manifest_dir, location, *manifest, extra_flags, error); | |
233 return extension; | |
234 } | |
235 | |
236 static scoped_refptr<Extension> LoadExtensionManifest( | |
237 const std::string& manifest_value, | |
238 const base::FilePath& manifest_dir, | |
239 Manifest::Location location, | |
240 int extra_flags, | |
241 std::string* error) { | |
242 JSONStringValueSerializer serializer(manifest_value); | |
243 scoped_ptr<base::Value> result(serializer.Deserialize(NULL, error)); | |
244 if (!result.get()) | |
245 return NULL; | |
246 CHECK_EQ(base::Value::TYPE_DICTIONARY, result->GetType()); | |
247 return LoadExtensionManifest( | |
248 static_cast<base::DictionaryValue*>(result.get()), | |
249 manifest_dir, | |
250 location, | |
251 extra_flags, | |
252 error); | |
253 } | |
254 | |
255 TEST_F(ExtensionFileUtilTest, ValidateThemeUTF8) { | |
256 base::ScopedTempDir temp; | |
257 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
258 | |
259 // "aeo" with accents. Use http://0xcc.net/jsescape/ to decode them. | |
260 std::string non_ascii_file = "\xC3\xA0\xC3\xA8\xC3\xB2.png"; | |
261 base::FilePath non_ascii_path = | |
262 temp.path().Append(base::FilePath::FromUTF8Unsafe(non_ascii_file)); | |
263 base::WriteFile(non_ascii_path, "", 0); | |
264 | |
265 std::string kManifest = | |
266 base::StringPrintf( | |
267 "{ \"name\": \"Test\", \"version\": \"1.0\", " | |
268 " \"theme\": { \"images\": { \"theme_frame\": \"%s\" } }" | |
269 "}", non_ascii_file.c_str()); | |
270 std::string error; | |
271 scoped_refptr<Extension> extension = LoadExtensionManifest( | |
272 kManifest, temp.path(), Manifest::UNPACKED, 0, &error); | |
273 ASSERT_TRUE(extension.get()) << error; | |
274 | |
275 std::vector<extensions::InstallWarning> warnings; | |
276 EXPECT_TRUE(extension_file_util::ValidateExtension( | |
277 extension.get(), &error, &warnings)) << error; | |
278 EXPECT_EQ(0U, warnings.size()); | |
279 } | |
280 | |
281 TEST_F(ExtensionFileUtilTest, BackgroundScriptsMustExist) { | |
282 base::ScopedTempDir temp; | |
283 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
284 | |
285 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | |
286 value->SetString("name", "test"); | |
287 value->SetString("version", "1"); | |
288 value->SetInteger("manifest_version", 1); | |
289 | |
290 base::ListValue* scripts = new base::ListValue(); | |
291 scripts->Append(new base::StringValue("foo.js")); | |
292 value->Set("background.scripts", scripts); | |
293 | |
294 std::string error; | |
295 std::vector<extensions::InstallWarning> warnings; | |
296 scoped_refptr<Extension> extension = LoadExtensionManifest( | |
297 value.get(), temp.path(), Manifest::UNPACKED, 0, &error); | |
298 ASSERT_TRUE(extension.get()) << error; | |
299 | |
300 EXPECT_FALSE(extension_file_util::ValidateExtension( | |
301 extension.get(), &error, &warnings)); | |
302 EXPECT_EQ(l10n_util::GetStringFUTF8( | |
303 IDS_EXTENSION_LOAD_BACKGROUND_SCRIPT_FAILED, | |
304 base::ASCIIToUTF16("foo.js")), | |
305 error); | |
306 EXPECT_EQ(0U, warnings.size()); | |
307 | |
308 scripts->Clear(); | |
309 scripts->Append(new base::StringValue("http://google.com/foo.js")); | |
310 | |
311 extension = LoadExtensionManifest(value.get(), temp.path(), | |
312 Manifest::UNPACKED, 0, &error); | |
313 ASSERT_TRUE(extension.get()) << error; | |
314 | |
315 warnings.clear(); | |
316 EXPECT_FALSE(extension_file_util::ValidateExtension( | |
317 extension.get(), &error, &warnings)); | |
318 EXPECT_EQ(l10n_util::GetStringFUTF8( | |
319 IDS_EXTENSION_LOAD_BACKGROUND_SCRIPT_FAILED, | |
320 base::ASCIIToUTF16("http://google.com/foo.js")), | |
321 error); | |
322 EXPECT_EQ(0U, warnings.size()); | |
323 } | |
324 | |
325 // Private key, generated by Chrome specifically for this test, and | |
326 // never used elsewhere. | |
327 const char private_key[] = | |
328 "-----BEGIN PRIVATE KEY-----\n" | |
329 "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKt02SR0FYaYy6fpW\n" | |
330 "MAA+kU1BgK3d+OmmWfdr+JATIjhRkyeSF4lTd/71JQsyKqPzYkQPi3EeROWM+goTv\n" | |
331 "EhJqq07q63BolpsFmlV+S4ny+sBA2B4aWwRYXlBWikdrQSA0mJMzvEHc6nKzBgXik\n" | |
332 "QSVbyyBNAsxlDB9WaCxRVOpK3AgMBAAECgYBGvSPlrVtAOAQ2V8j9FqorKZA8SLPX\n" | |
333 "IeJC/yzU3RB2nPMjI17aMOvrUHxJUhzMeh4jwabVvSzzDtKFozPGupW3xaI8sQdi2\n" | |
334 "WWMTQIk/Q9HHDWoQ9qA6SwX2qWCc5SyjCKqVp78ye+000kqTJYjBsDgXeAlzKcx2B\n" | |
335 "4GAAeWonDdkQJBANNb8wrqNWFn7DqyQTfELzcRTRnqQ/r1pdeJo6obzbnwGnlqe3t\n" | |
336 "KhLjtJNIGrQg5iC0OVLWFuvPJs0t3z62A1ckCQQDPq2JZuwTwu5Pl4DJ0r9O1FdqN\n" | |
337 "JgqPZyMptokCDQ3khLLGakIu+TqB9YtrzI69rJMSG2Egb+6McaDX+dh3XmR/AkB9t\n" | |
338 "xJf6qDnmA2td/tMtTc0NOk8Qdg/fD8xbZ/YfYMnVoYYs9pQoilBaWRePDRNURMLYZ\n" | |
339 "vHAI0Llmw7tj7jv17pAkEAz44uXRpjRKtllUIvi5pUENAHwDz+HvdpGH68jpU3hmb\n" | |
340 "uOwrmnQYxaMReFV68Z2w9DcLZn07f7/R9Wn72z89CxwJAFsDoNaDes4h48bX7plct\n" | |
341 "s9ACjmTwcCigZjN2K7AGv7ntCLF3DnV5dK0dTHNaAdD3SbY3jl29Rk2CwiURSX6Ee\n" | |
342 "g==\n" | |
343 "-----END PRIVATE KEY-----\n"; | |
344 | |
345 TEST_F(ExtensionFileUtilTest, FindPrivateKeyFiles) { | |
346 base::ScopedTempDir temp; | |
347 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
348 | |
349 base::FilePath src_path = temp.path().AppendASCII("some_dir"); | |
350 ASSERT_TRUE(base::CreateDirectory(src_path)); | |
351 | |
352 ASSERT_TRUE(base::WriteFile(src_path.AppendASCII("a_key.pem"), | |
353 private_key, arraysize(private_key))); | |
354 ASSERT_TRUE(base::WriteFile(src_path.AppendASCII("second_key.pem"), | |
355 private_key, arraysize(private_key))); | |
356 // Shouldn't find a key with a different extension. | |
357 ASSERT_TRUE(base::WriteFile(src_path.AppendASCII("key.diff_ext"), | |
358 private_key, arraysize(private_key))); | |
359 // Shouldn't find a key that isn't parsable. | |
360 ASSERT_TRUE(base::WriteFile(src_path.AppendASCII("unparsable_key.pem"), | |
361 private_key, arraysize(private_key) - 30)); | |
362 std::vector<base::FilePath> private_keys = | |
363 extension_file_util::FindPrivateKeyFiles(temp.path()); | |
364 EXPECT_EQ(2U, private_keys.size()); | |
365 EXPECT_THAT(private_keys, | |
366 testing::Contains(src_path.AppendASCII("a_key.pem"))); | |
367 EXPECT_THAT(private_keys, | |
368 testing::Contains(src_path.AppendASCII("second_key.pem"))); | |
369 } | |
370 | |
371 TEST_F(ExtensionFileUtilTest, WarnOnPrivateKey) { | |
372 base::ScopedTempDir temp; | |
373 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
374 | |
375 base::FilePath ext_path = temp.path().AppendASCII("ext_root"); | |
376 ASSERT_TRUE(base::CreateDirectory(ext_path)); | |
377 | |
378 const char manifest[] = | |
379 "{\n" | |
380 " \"name\": \"Test Extension\",\n" | |
381 " \"version\": \"1.0\",\n" | |
382 " \"manifest_version\": 2,\n" | |
383 " \"description\": \"The first extension that I made.\"\n" | |
384 "}\n"; | |
385 ASSERT_TRUE(base::WriteFile(ext_path.AppendASCII("manifest.json"), | |
386 manifest, strlen(manifest))); | |
387 ASSERT_TRUE(base::WriteFile(ext_path.AppendASCII("a_key.pem"), | |
388 private_key, strlen(private_key))); | |
389 | |
390 std::string error; | |
391 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | |
392 ext_path, "the_id", Manifest::EXTERNAL_PREF, | |
393 Extension::NO_FLAGS, &error)); | |
394 ASSERT_TRUE(extension.get()) << error; | |
395 ASSERT_EQ(1u, extension->install_warnings().size()); | |
396 EXPECT_THAT( | |
397 extension->install_warnings(), | |
398 testing::ElementsAre( | |
399 testing::Field( | |
400 &extensions::InstallWarning::message, | |
401 testing::ContainsRegex( | |
402 "extension includes the key file.*ext_root.a_key.pem")))); | |
403 | |
404 // Turn the warning into an error with ERROR_ON_PRIVATE_KEY. | |
405 extension = extension_file_util::LoadExtension( | |
406 ext_path, "the_id", Manifest::EXTERNAL_PREF, | |
407 Extension::ERROR_ON_PRIVATE_KEY, &error); | |
408 EXPECT_FALSE(extension.get()); | |
409 EXPECT_THAT(error, | |
410 testing::ContainsRegex( | |
411 "extension includes the key file.*ext_root.a_key.pem")); | |
412 } | |
413 | |
414 TEST_F(ExtensionFileUtilTest, CheckZeroLengthImageFile) { | |
415 base::FilePath install_dir; | |
416 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | |
417 | |
418 // Try to install an extension with a zero-length icon file. | |
419 base::FilePath ext_dir = install_dir.AppendASCII("extensions") | |
420 .AppendASCII("bad") | |
421 .AppendASCII("Extensions") | |
422 .AppendASCII("ffffffffffffffffffffffffffffffff"); | |
423 | |
424 std::string error; | |
425 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | |
426 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | |
427 EXPECT_TRUE(extension.get() == NULL); | |
428 EXPECT_STREQ("Could not load extension icon 'icon.png'.", error.c_str()); | |
429 | |
430 // Try to install an extension with a zero-length browser action icon file. | |
431 ext_dir = install_dir.AppendASCII("extensions") | |
432 .AppendASCII("bad") | |
433 .AppendASCII("Extensions") | |
434 .AppendASCII("gggggggggggggggggggggggggggggggg"); | |
435 | |
436 scoped_refptr<Extension> extension2(extension_file_util::LoadExtension( | |
437 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | |
438 EXPECT_TRUE(extension2.get() == NULL); | |
439 EXPECT_STREQ("Could not load icon 'icon.png' for browser action.", | |
440 error.c_str()); | |
441 | |
442 // Try to install an extension with a zero-length page action icon file. | |
443 ext_dir = install_dir.AppendASCII("extensions") | |
444 .AppendASCII("bad") | |
445 .AppendASCII("Extensions") | |
446 .AppendASCII("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); | |
447 | |
448 scoped_refptr<Extension> extension3(extension_file_util::LoadExtension( | |
449 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | |
450 EXPECT_TRUE(extension3.get() == NULL); | |
451 EXPECT_STREQ("Could not load icon 'icon.png' for page action.", | |
452 error.c_str()); | |
453 } | |
454 | |
455 // TODO(aa): More tests as motivation allows. Maybe steal some from | |
456 // ExtensionService? Many of them could probably be tested here without the | |
457 // MessageLoop shenanigans. | |
OLD | NEW |