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