| 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 "base/file_util.h" |
| 8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
| 9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | 107 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); |
| 108 install_dir = install_dir.AppendASCII("extensions") | 108 install_dir = install_dir.AppendASCII("extensions") |
| 109 .AppendASCII("good") | 109 .AppendASCII("good") |
| 110 .AppendASCII("Extensions") | 110 .AppendASCII("Extensions") |
| 111 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") | 111 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") |
| 112 .AppendASCII("1.0.0.0"); | 112 .AppendASCII("1.0.0.0"); |
| 113 | 113 |
| 114 std::string error; | 114 std::string error; |
| 115 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | 115 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( |
| 116 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 116 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 117 ASSERT_TRUE(extension != NULL); | 117 ASSERT_TRUE(extension.get() != NULL); |
| 118 EXPECT_EQ("The first extension that I made.", extension->description()); | 118 EXPECT_EQ("The first extension that I made.", extension->description()); |
| 119 } | 119 } |
| 120 | 120 |
| 121 TEST_F(ExtensionFileUtilTest, LoadExtensionWithoutLocalesFolder) { | 121 TEST_F(ExtensionFileUtilTest, LoadExtensionWithoutLocalesFolder) { |
| 122 base::FilePath install_dir; | 122 base::FilePath install_dir; |
| 123 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | 123 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); |
| 124 install_dir = install_dir.AppendASCII("extensions") | 124 install_dir = install_dir.AppendASCII("extensions") |
| 125 .AppendASCII("good") | 125 .AppendASCII("good") |
| 126 .AppendASCII("Extensions") | 126 .AppendASCII("Extensions") |
| 127 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa") | 127 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa") |
| 128 .AppendASCII("1.0"); | 128 .AppendASCII("1.0"); |
| 129 | 129 |
| 130 std::string error; | 130 std::string error; |
| 131 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | 131 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( |
| 132 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 132 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 133 ASSERT_FALSE(extension == NULL); | 133 ASSERT_FALSE(extension.get() == NULL); |
| 134 EXPECT_TRUE(error.empty()); | 134 EXPECT_TRUE(error.empty()); |
| 135 } | 135 } |
| 136 | 136 |
| 137 TEST_F(ExtensionFileUtilTest, CheckIllegalFilenamesNoUnderscores) { | 137 TEST_F(ExtensionFileUtilTest, CheckIllegalFilenamesNoUnderscores) { |
| 138 base::ScopedTempDir temp; | 138 base::ScopedTempDir temp; |
| 139 ASSERT_TRUE(temp.CreateUniqueTempDir()); | 139 ASSERT_TRUE(temp.CreateUniqueTempDir()); |
| 140 | 140 |
| 141 base::FilePath src_path = temp.path().AppendASCII("some_dir"); | 141 base::FilePath src_path = temp.path().AppendASCII("some_dir"); |
| 142 ASSERT_TRUE(file_util::CreateDirectory(src_path)); | 142 ASSERT_TRUE(file_util::CreateDirectory(src_path)); |
| 143 | 143 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | 187 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); |
| 188 install_dir = install_dir.AppendASCII("extensions") | 188 install_dir = install_dir.AppendASCII("extensions") |
| 189 .AppendASCII("bad") | 189 .AppendASCII("bad") |
| 190 .AppendASCII("Extensions") | 190 .AppendASCII("Extensions") |
| 191 .AppendASCII("dddddddddddddddddddddddddddddddd") | 191 .AppendASCII("dddddddddddddddddddddddddddddddd") |
| 192 .AppendASCII("1.0"); | 192 .AppendASCII("1.0"); |
| 193 | 193 |
| 194 std::string error; | 194 std::string error; |
| 195 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | 195 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( |
| 196 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 196 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 197 ASSERT_TRUE(extension == NULL); | 197 ASSERT_TRUE(extension.get() == NULL); |
| 198 ASSERT_FALSE(error.empty()); | 198 ASSERT_FALSE(error.empty()); |
| 199 ASSERT_STREQ("Manifest file is missing or unreadable.", error.c_str()); | 199 ASSERT_STREQ("Manifest file is missing or unreadable.", error.c_str()); |
| 200 } | 200 } |
| 201 | 201 |
| 202 TEST_F(ExtensionFileUtilTest, LoadExtensionGivesHelpfullErrorOnBadManifest) { | 202 TEST_F(ExtensionFileUtilTest, LoadExtensionGivesHelpfullErrorOnBadManifest) { |
| 203 base::FilePath install_dir; | 203 base::FilePath install_dir; |
| 204 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | 204 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); |
| 205 install_dir = install_dir.AppendASCII("extensions") | 205 install_dir = install_dir.AppendASCII("extensions") |
| 206 .AppendASCII("bad") | 206 .AppendASCII("bad") |
| 207 .AppendASCII("Extensions") | 207 .AppendASCII("Extensions") |
| 208 .AppendASCII("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") | 208 .AppendASCII("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") |
| 209 .AppendASCII("1.0"); | 209 .AppendASCII("1.0"); |
| 210 | 210 |
| 211 std::string error; | 211 std::string error; |
| 212 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | 212 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( |
| 213 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 213 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 214 ASSERT_TRUE(extension == NULL); | 214 ASSERT_TRUE(extension.get() == NULL); |
| 215 ASSERT_FALSE(error.empty()); | 215 ASSERT_FALSE(error.empty()); |
| 216 ASSERT_STREQ("Manifest is not valid JSON. " | 216 ASSERT_STREQ("Manifest is not valid JSON. " |
| 217 "Line: 2, column: 16, Syntax error.", error.c_str()); | 217 "Line: 2, column: 16, Syntax error.", error.c_str()); |
| 218 } | 218 } |
| 219 | 219 |
| 220 TEST_F(ExtensionFileUtilTest, FailLoadingNonUTF8Scripts) { | 220 TEST_F(ExtensionFileUtilTest, FailLoadingNonUTF8Scripts) { |
| 221 base::FilePath install_dir; | 221 base::FilePath install_dir; |
| 222 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); | 222 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir)); |
| 223 install_dir = install_dir.AppendASCII("extensions") | 223 install_dir = install_dir.AppendASCII("extensions") |
| 224 .AppendASCII("bad") | 224 .AppendASCII("bad") |
| 225 .AppendASCII("bad_encoding"); | 225 .AppendASCII("bad_encoding"); |
| 226 | 226 |
| 227 std::string error; | 227 std::string error; |
| 228 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | 228 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( |
| 229 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 229 install_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 230 ASSERT_TRUE(extension == NULL); | 230 ASSERT_TRUE(extension.get() == NULL); |
| 231 ASSERT_STREQ("Could not load file 'bad_encoding.js' for content script. " | 231 ASSERT_STREQ("Could not load file 'bad_encoding.js' for content script. " |
| 232 "It isn't UTF-8 encoded.", error.c_str()); | 232 "It isn't UTF-8 encoded.", |
| 233 error.c_str()); |
| 233 } | 234 } |
| 234 | 235 |
| 235 TEST_F(ExtensionFileUtilTest, ExtensionURLToRelativeFilePath) { | 236 TEST_F(ExtensionFileUtilTest, ExtensionURLToRelativeFilePath) { |
| 236 #define URL_PREFIX "chrome-extension://extension-id/" | 237 #define URL_PREFIX "chrome-extension://extension-id/" |
| 237 struct TestCase { | 238 struct TestCase { |
| 238 const char* url; | 239 const char* url; |
| 239 const char* expected_relative_path; | 240 const char* expected_relative_path; |
| 240 } test_cases[] = { | 241 } test_cases[] = { |
| 241 { URL_PREFIX "simple.html", | 242 { URL_PREFIX "simple.html", |
| 242 "simple.html" }, | 243 "simple.html" }, |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 base::StringPrintf( | 386 base::StringPrintf( |
| 386 "{ \"name\": \"Test\", \"version\": \"1.0\", " | 387 "{ \"name\": \"Test\", \"version\": \"1.0\", " |
| 387 " \"theme\": { \"images\": { \"theme_frame\": \"%s\" } }" | 388 " \"theme\": { \"images\": { \"theme_frame\": \"%s\" } }" |
| 388 "}", non_ascii_file.c_str()); | 389 "}", non_ascii_file.c_str()); |
| 389 std::string error; | 390 std::string error; |
| 390 scoped_refptr<Extension> extension = LoadExtensionManifest( | 391 scoped_refptr<Extension> extension = LoadExtensionManifest( |
| 391 kManifest, temp.path(), Manifest::UNPACKED, 0, &error); | 392 kManifest, temp.path(), Manifest::UNPACKED, 0, &error); |
| 392 ASSERT_TRUE(extension.get()) << error; | 393 ASSERT_TRUE(extension.get()) << error; |
| 393 | 394 |
| 394 std::vector<extensions::InstallWarning> warnings; | 395 std::vector<extensions::InstallWarning> warnings; |
| 395 EXPECT_TRUE(extension_file_util::ValidateExtension(extension, | 396 EXPECT_TRUE(extension_file_util::ValidateExtension( |
| 396 &error, &warnings)) << | 397 extension.get(), &error, &warnings)) << error; |
| 397 error; | |
| 398 EXPECT_EQ(0U, warnings.size()); | 398 EXPECT_EQ(0U, warnings.size()); |
| 399 } | 399 } |
| 400 | 400 |
| 401 TEST_F(ExtensionFileUtilTest, BackgroundScriptsMustExist) { | 401 TEST_F(ExtensionFileUtilTest, BackgroundScriptsMustExist) { |
| 402 base::ScopedTempDir temp; | 402 base::ScopedTempDir temp; |
| 403 ASSERT_TRUE(temp.CreateUniqueTempDir()); | 403 ASSERT_TRUE(temp.CreateUniqueTempDir()); |
| 404 | 404 |
| 405 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | 405 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); |
| 406 value->SetString("name", "test"); | 406 value->SetString("name", "test"); |
| 407 value->SetString("version", "1"); | 407 value->SetString("version", "1"); |
| 408 value->SetInteger("manifest_version", 1); | 408 value->SetInteger("manifest_version", 1); |
| 409 | 409 |
| 410 base::ListValue* scripts = new base::ListValue(); | 410 base::ListValue* scripts = new base::ListValue(); |
| 411 scripts->Append(new base::StringValue("foo.js")); | 411 scripts->Append(new base::StringValue("foo.js")); |
| 412 value->Set("background.scripts", scripts); | 412 value->Set("background.scripts", scripts); |
| 413 | 413 |
| 414 std::string error; | 414 std::string error; |
| 415 std::vector<extensions::InstallWarning> warnings; | 415 std::vector<extensions::InstallWarning> warnings; |
| 416 scoped_refptr<Extension> extension = LoadExtensionManifest( | 416 scoped_refptr<Extension> extension = LoadExtensionManifest( |
| 417 value.get(), temp.path(), Manifest::UNPACKED, 0, &error); | 417 value.get(), temp.path(), Manifest::UNPACKED, 0, &error); |
| 418 ASSERT_TRUE(extension.get()) << error; | 418 ASSERT_TRUE(extension.get()) << error; |
| 419 | 419 |
| 420 EXPECT_FALSE(extension_file_util::ValidateExtension(extension, | 420 EXPECT_FALSE(extension_file_util::ValidateExtension( |
| 421 &error, &warnings)); | 421 extension.get(), &error, &warnings)); |
| 422 EXPECT_EQ(l10n_util::GetStringFUTF8( | 422 EXPECT_EQ(l10n_util::GetStringFUTF8( |
| 423 IDS_EXTENSION_LOAD_BACKGROUND_SCRIPT_FAILED, ASCIIToUTF16("foo.js")), | 423 IDS_EXTENSION_LOAD_BACKGROUND_SCRIPT_FAILED, ASCIIToUTF16("foo.js")), |
| 424 error); | 424 error); |
| 425 EXPECT_EQ(0U, warnings.size()); | 425 EXPECT_EQ(0U, warnings.size()); |
| 426 | 426 |
| 427 scripts->Clear(); | 427 scripts->Clear(); |
| 428 scripts->Append(new base::StringValue("http://google.com/foo.js")); | 428 scripts->Append(new base::StringValue("http://google.com/foo.js")); |
| 429 | 429 |
| 430 extension = LoadExtensionManifest(value.get(), temp.path(), | 430 extension = LoadExtensionManifest(value.get(), temp.path(), |
| 431 Manifest::UNPACKED, 0, &error); | 431 Manifest::UNPACKED, 0, &error); |
| 432 ASSERT_TRUE(extension.get()) << error; | 432 ASSERT_TRUE(extension.get()) << error; |
| 433 | 433 |
| 434 warnings.clear(); | 434 warnings.clear(); |
| 435 EXPECT_FALSE(extension_file_util::ValidateExtension(extension, | 435 EXPECT_FALSE(extension_file_util::ValidateExtension( |
| 436 &error, &warnings)); | 436 extension.get(), &error, &warnings)); |
| 437 EXPECT_EQ(l10n_util::GetStringFUTF8( | 437 EXPECT_EQ(l10n_util::GetStringFUTF8( |
| 438 IDS_EXTENSION_LOAD_BACKGROUND_SCRIPT_FAILED, | 438 IDS_EXTENSION_LOAD_BACKGROUND_SCRIPT_FAILED, |
| 439 ASCIIToUTF16("http://google.com/foo.js")), | 439 ASCIIToUTF16("http://google.com/foo.js")), |
| 440 error); | 440 error); |
| 441 EXPECT_EQ(0U, warnings.size()); | 441 EXPECT_EQ(0U, warnings.size()); |
| 442 } | 442 } |
| 443 | 443 |
| 444 // Private key, generated by Chrome specifically for this test, and | 444 // Private key, generated by Chrome specifically for this test, and |
| 445 // never used elsewhere. | 445 // never used elsewhere. |
| 446 const char private_key[] = | 446 const char private_key[] = |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 | 536 |
| 537 // Try to install an extension with a zero-length icon file. | 537 // Try to install an extension with a zero-length icon file. |
| 538 base::FilePath ext_dir = install_dir.AppendASCII("extensions") | 538 base::FilePath ext_dir = install_dir.AppendASCII("extensions") |
| 539 .AppendASCII("bad") | 539 .AppendASCII("bad") |
| 540 .AppendASCII("Extensions") | 540 .AppendASCII("Extensions") |
| 541 .AppendASCII("ffffffffffffffffffffffffffffffff"); | 541 .AppendASCII("ffffffffffffffffffffffffffffffff"); |
| 542 | 542 |
| 543 std::string error; | 543 std::string error; |
| 544 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( | 544 scoped_refptr<Extension> extension(extension_file_util::LoadExtension( |
| 545 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 545 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 546 EXPECT_TRUE(extension == NULL); | 546 EXPECT_TRUE(extension.get() == NULL); |
| 547 EXPECT_STREQ("Could not load extension icon 'icon.png'.", | 547 EXPECT_STREQ("Could not load extension icon 'icon.png'.", error.c_str()); |
| 548 error.c_str()); | |
| 549 | 548 |
| 550 // Try to install an extension with a zero-length browser action icon file. | 549 // Try to install an extension with a zero-length browser action icon file. |
| 551 ext_dir = install_dir.AppendASCII("extensions") | 550 ext_dir = install_dir.AppendASCII("extensions") |
| 552 .AppendASCII("bad") | 551 .AppendASCII("bad") |
| 553 .AppendASCII("Extensions") | 552 .AppendASCII("Extensions") |
| 554 .AppendASCII("gggggggggggggggggggggggggggggggg"); | 553 .AppendASCII("gggggggggggggggggggggggggggggggg"); |
| 555 | 554 |
| 556 scoped_refptr<Extension> extension2(extension_file_util::LoadExtension( | 555 scoped_refptr<Extension> extension2(extension_file_util::LoadExtension( |
| 557 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 556 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 558 EXPECT_TRUE(extension2 == NULL); | 557 EXPECT_TRUE(extension2.get() == NULL); |
| 559 EXPECT_STREQ("Could not load icon 'icon.png' for browser action.", | 558 EXPECT_STREQ("Could not load icon 'icon.png' for browser action.", |
| 560 error.c_str()); | 559 error.c_str()); |
| 561 | 560 |
| 562 // Try to install an extension with a zero-length page action icon file. | 561 // Try to install an extension with a zero-length page action icon file. |
| 563 ext_dir = install_dir.AppendASCII("extensions") | 562 ext_dir = install_dir.AppendASCII("extensions") |
| 564 .AppendASCII("bad") | 563 .AppendASCII("bad") |
| 565 .AppendASCII("Extensions") | 564 .AppendASCII("Extensions") |
| 566 .AppendASCII("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); | 565 .AppendASCII("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); |
| 567 | 566 |
| 568 scoped_refptr<Extension> extension3(extension_file_util::LoadExtension( | 567 scoped_refptr<Extension> extension3(extension_file_util::LoadExtension( |
| 569 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); | 568 ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error)); |
| 570 EXPECT_TRUE(extension3 == NULL); | 569 EXPECT_TRUE(extension3.get() == NULL); |
| 571 EXPECT_STREQ("Could not load icon 'icon.png' for page action.", | 570 EXPECT_STREQ("Could not load icon 'icon.png' for page action.", |
| 572 error.c_str()); | 571 error.c_str()); |
| 573 } | 572 } |
| 574 | 573 |
| 575 // TODO(aa): More tests as motivation allows. Maybe steal some from | 574 // TODO(aa): More tests as motivation allows. Maybe steal some from |
| 576 // ExtensionService? Many of them could probably be tested here without the | 575 // ExtensionService? Many of them could probably be tested here without the |
| 577 // MessageLoop shenanigans. | 576 // MessageLoop shenanigans. |
| OLD | NEW |