diff options
30 files changed, 325 insertions, 305 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b3b9b32..1f309da 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -4742,28 +4742,6 @@ Even if you have downloaded files from this website before, the website might ha <message name="IDS_EXTENSION_LOAD_ICON_FOR_BROWSER_ACTION_FAILED" desc=""> Could not load icon '<ph name="ICON">$1<ex>icon.png</ex></ph>' for browser action. </message> - <if expr="is_win"> - <message name="IDS_EXTENSION_UNPACK_FAILED" desc="On windows, it is possible to mount a disk without the root of that disk having a drive letter. The sandbox does not support this. See crbug/49530 ."> - Can not unpack extension. To safely unpack an extension, there must be a path to your profile directory that starts with a drive letter and does not contain a junction, mount point, or symlink. No such path exists for your profile. - </message> - </if> - <if expr="not is_win"> - <message name="IDS_EXTENSION_UNPACK_FAILED" desc=""> - Can not unpack extension. To safely unpack an extension, there must be a path to your profile directory that does not contain a symlink. No such path exists for your profile. - </message> - </if> - <message name="IDS_EXTENSION_PACKAGE_ERROR_MESSAGE" desc="The cases where we get an error message string back from some other component. The message might be in English, but these are typically developer errors, and the extension SDK is English."> - Package is invalid. Details: '<ph name="ERROR_MESSAGE">$1<ex>error</ex></ph>'. - </message> - <message name="IDS_EXTENSION_PACKAGE_ERROR_CODE" desc="Error message in cases where we fail to install the extension because the crx file is invalid. For example, because the crx header or signature is invalid."> - Package is invalid: '<ph name="ERROR_CODE">$1<ex>error</ex></ph>'. - </message> - <message name="IDS_EXTENSION_PACKAGE_INSTALL_ERROR" desc="Error message in case package fails to install because of some problem with the filesystem."> - Could not install package: '<ph name="ERROR_CODE">$1<ex>error</ex></ph>' - </message> - <message name="IDS_EXTENSION_INSTALL_PROCESS_CRASHED" desc="Error message in case package fails to install because a utility process crashed."> - Could not install package because a utility process crashed. Try restarting Chrome and trying again. - </message> <!-- Extension installed bubble --> <message name="IDS_EXTENSION_BUNDLE_INSTALLED_HEADING_EXTENSIONS" desc="First line in the content area of the extension bundle installed bubble. Instructs which extensions were installed."> diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc index 2dc37c8..e9b34015 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc @@ -19,7 +19,6 @@ #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_util.h" -#include "chrome/browser/extensions/sandboxed_unpacker.h" #include "chrome/browser/extensions/webstore_data_fetcher.h" #include "chrome/browser/extensions/webstore_install_helper.h" #include "chrome/browser/image_decoder.h" @@ -27,6 +26,7 @@ #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/image_loader.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/constants.h" #include "extensions/common/extension_urls.h" #include "extensions/common/manifest.h" diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h index 4058d40..dd02095 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h +++ b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h @@ -10,7 +10,7 @@ #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" -#include "chrome/browser/extensions/sandboxed_unpacker.h" +#include "extensions/browser/sandboxed_unpacker.h" namespace extensions { class Extension; diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc index 8f58335..bcef462 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc @@ -14,9 +14,9 @@ #include "base/version.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/ui/kiosk_external_update_notification.h" -#include "chrome/browser/extensions/sandboxed_unpacker.h" #include "chrome/common/chrome_version_info.h" #include "content/public/browser/browser_thread.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/extension.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index bb9083e..769ca30 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -13,14 +13,13 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/version.h" -#include "chrome/browser/extensions/blacklist.h" #include "chrome/browser/extensions/extension_install_checker.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/sandboxed_unpacker.h" #include "chrome/browser/extensions/webstore_installer.h" #include "chrome/common/extensions/extension_constants.h" #include "extensions/browser/install_flag.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/extension.h" #include "extensions/common/manifest.h" #include "sync/api/string_ordinal.h" diff --git a/chrome/browser/extensions/startup_helper.cc b/chrome/browser/extensions/startup_helper.cc index 4432e7f..a69f73d 100644 --- a/chrome/browser/extensions/startup_helper.cc +++ b/chrome/browser/extensions/startup_helper.cc @@ -14,7 +14,6 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/sandboxed_unpacker.h" #include "chrome/browser/extensions/webstore_startup_installer.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_switches.h" @@ -22,6 +21,7 @@ #include "components/crx_file/id_util.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/extension.h" #include "ipc/ipc_message.h" @@ -298,7 +298,7 @@ void AppInstallHelper::OnAppInstallComplete(bool success, const std::string& error, webstore_install::Result result) { success_ = success; - error_= error; + error_ = error; done_callback_.Run(); } diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index ed4456d..7988eb9 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -755,8 +755,6 @@ 'browser/extensions/proxy_overridden_bubble_controller.h', 'browser/extensions/requirements_checker.cc', 'browser/extensions/requirements_checker.h', - 'browser/extensions/sandboxed_unpacker.cc', - 'browser/extensions/sandboxed_unpacker.h', 'browser/extensions/settings_api_bubble_controller.cc', 'browser/extensions/settings_api_bubble_controller.h', 'browser/extensions/settings_api_helpers.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 7f451bd..a235300 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -783,7 +783,6 @@ 'browser/extensions/permission_messages_unittest.cc', 'browser/extensions/permissions_based_management_policy_provider_unittest.cc', 'browser/extensions/permissions_updater_unittest.cc', - 'browser/extensions/sandboxed_unpacker_unittest.cc', 'browser/extensions/shared_module_service_unittest.cc', 'browser/extensions/standard_management_policy_provider_unittest.cc', 'browser/extensions/token_cache/token_cache_service_unittest.cc', diff --git a/chrome/common/extensions/chrome_utility_extensions_messages.h b/chrome/common/extensions/chrome_utility_extensions_messages.h index 45fffec..2d9c8f4 100644 --- a/chrome/common/extensions/chrome_utility_extensions_messages.h +++ b/chrome/common/extensions/chrome_utility_extensions_messages.h @@ -75,14 +75,6 @@ IPC_STRUCT_TRAITS_END() // Utility process messages: // These are messages from the browser to the utility process. -// Tells the utility process to unpack the given extension file in its -// directory and verify that it is valid. -IPC_MESSAGE_CONTROL4(ChromeUtilityMsg_UnpackExtension, - base::FilePath /* extension_filename */, - std::string /* extension_id */, - int /* Manifest::Location */, - int /* InitFromValue flags */) - IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_UnzipToDir, base::FilePath /* zip_file */, base::FilePath /* dir */) @@ -162,21 +154,6 @@ IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_ImageWriter_Cancel) // Utility process host messages: // These are messages from the utility process to the browser. -// Reply when the utility process is done unpacking an extension. |manifest| -// is the parsed manifest.json file. -// The unpacker should also have written out files containing the decoded -// images and message catalogs from the extension. The data is written into a -// DecodedImages struct into a file named kDecodedImagesFilename in the -// directory that was passed in. This is done because the data is too large to -// pass over IPC. -IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_UnpackExtension_Succeeded, - base::DictionaryValue /* manifest */) - -// Reply when the utility process has failed while unpacking an extension. -// |error_message| is a user-displayable explanation of what went wrong. -IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_UnpackExtension_Failed, - base::string16 /* error_message, if any */) - // Reply when the utility process is done unzipping a file. |unpacked_path| // is the directory which contains the unzipped contents. IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_UnzipToDir_Succeeded, diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 25a7444..e06aebc 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc @@ -109,7 +109,7 @@ ChromeContentUtilityClient::~ChromeContentUtilityClient() { void ChromeContentUtilityClient::UtilityThreadStarted() { #if defined(ENABLE_EXTENSIONS) - extensions::ExtensionsHandler::UtilityThreadStarted(); + extensions::UtilityHandler::UtilityThreadStarted(); #endif if (kMessageWhitelistSize > 0) { diff --git a/chrome/utility/extensions/extensions_handler.cc b/chrome/utility/extensions/extensions_handler.cc index 06d83c0..72930f5 100644 --- a/chrome/utility/extensions/extensions_handler.cc +++ b/chrome/utility/extensions/extensions_handler.cc @@ -17,7 +17,6 @@ #include "extensions/common/extension.h" #include "extensions/common/extension_l10n_util.h" #include "extensions/common/extension_utility_messages.h" -#include "extensions/common/manifest.h" #include "extensions/utility/unpacker.h" #include "media/base/media.h" #include "media/base/media_file_checker.h" @@ -59,6 +58,7 @@ const char kExtensionHandlerUnzipError[] = } // namespace ExtensionsHandler::ExtensionsHandler() { + ExtensionsClient::Set(ChromeExtensionsClient::GetInstance()); } ExtensionsHandler::~ExtensionsHandler() { @@ -76,15 +76,9 @@ void ExtensionsHandler::PreSandboxStartup() { media::InitializeMediaLibrary(media_path); } -// static -void ExtensionsHandler::UtilityThreadStarted() { - UtilityHandler::UtilityThreadStarted(); -} - bool ExtensionsHandler::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(ExtensionsHandler, message) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnpackExtension, OnUnpackExtension) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnzipToDir, OnUnzipToDir) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImageBase64, OnDecodeImageBase64) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CheckMediaFile, OnCheckMediaFile) @@ -117,30 +111,6 @@ bool ExtensionsHandler::OnMessageReceived(const IPC::Message& message) { return handled || utility_handler_.OnMessageReceived(message); } -void ExtensionsHandler::OnUnpackExtension( - const base::FilePath& extension_path, - const std::string& extension_id, - int location, - int creation_flags) { - CHECK_GT(location, Manifest::INVALID_LOCATION); - CHECK_LT(location, Manifest::NUM_LOCATIONS); - ExtensionsClient::Set(ChromeExtensionsClient::GetInstance()); - Unpacker unpacker(extension_path, - extension_id, - static_cast<Manifest::Location>(location), - creation_flags); - if (unpacker.Run() && unpacker.DumpImagesToFile() && - unpacker.DumpMessageCatalogsToFile()) { - Send(new ChromeUtilityHostMsg_UnpackExtension_Succeeded( - *unpacker.parsed_manifest())); - } else { - Send(new ChromeUtilityHostMsg_UnpackExtension_Failed( - unpacker.error_message())); - } - - ReleaseProcessIfNeeded(); -} - void ExtensionsHandler::OnUnzipToDir(const base::FilePath& zip_path, const base::FilePath& dir) { if (!zip::Unzip(zip_path, dir)) { diff --git a/chrome/utility/extensions/extensions_handler.h b/chrome/utility/extensions/extensions_handler.h index 3a001b1..aeae769 100644 --- a/chrome/utility/extensions/extensions_handler.h +++ b/chrome/utility/extensions/extensions_handler.h @@ -29,16 +29,12 @@ class ExtensionsHandler : public UtilityMessageHandler { ~ExtensionsHandler() override; static void PreSandboxStartup(); - static void UtilityThreadStarted(); // UtilityMessageHandler: bool OnMessageReceived(const IPC::Message& message) override; private: // IPC message handlers. - void OnUnpackExtension(const base::FilePath& extension_path, - const std::string& extension_id, - int location, int creation_flags); void OnUnzipToDir(const base::FilePath& zip_path, const base::FilePath& dir); void OnDecodeImageBase64(const std::string& encoded_data); void OnCheckMediaFile(int64 milliseconds_of_decoding, diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn index de53a9d..6fa4f48 100644 --- a/extensions/BUILD.gn +++ b/extensions/BUILD.gn @@ -102,6 +102,8 @@ source_set("test_support") { "test/extension_test_message_listener.h", "test/result_catcher.cc", "test/result_catcher.h", + "test/test_content_utility_client.cc", + "test/test_content_utility_client.h", "test/test_extensions_client.cc", "test/test_extensions_client.h", "test/test_permission_message_provider.cc", @@ -212,6 +214,7 @@ if (false) { "browser/process_map_unittest.cc", "browser/quota_service_unittest.cc", "browser/runtime_data_unittest.cc", + "browser/sandboxed_unpacker_unittest.cc", "browser/value_store/leveldb_value_store_unittest.cc", "browser/value_store/testing_value_store_unittest.cc", "browser/value_store/value_store_change_unittest.cc", diff --git a/extensions/DEPS b/extensions/DEPS index 183bba6..a5faa35 100644 --- a/extensions/DEPS +++ b/extensions/DEPS @@ -11,9 +11,9 @@ include_rules = [ "+extensions/test", "+grit/extensions_renderer_resources.h", "+grit/extensions_resources.h", + "+testing", "+third_party/mojo/src/mojo/public", "+third_party/skia/include", - "+testing", # Minimal UI dependencies. There are two good rules for UI dependencies here: # diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 9cecc6c..092badd 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn @@ -475,6 +475,8 @@ source_set("browser") { "renderer_startup_helper.h", "runtime_data.cc", "runtime_data.h", + "sandboxed_unpacker.cc", + "sandboxed_unpacker.h", "script_execution_observer.h", "script_executor.cc", "script_executor.h", diff --git a/extensions/browser/extensions_test.cc b/extensions/browser/extensions_test.cc index 5b7a8ce..103ade0 100644 --- a/extensions/browser/extensions_test.cc +++ b/extensions/browser/extensions_test.cc @@ -9,6 +9,7 @@ #include "content/public/common/content_client.h" #include "content/public/test/test_browser_context.h" #include "extensions/browser/test_extensions_browser_client.h" +#include "extensions/test/test_content_utility_client.h" namespace extensions { @@ -22,11 +23,13 @@ namespace extensions { // }; ExtensionsTest::ExtensionsTest() : content_client_(new content::ContentClient), + content_utility_client_(new TestContentUtilityClient), content_browser_client_(new content::ContentBrowserClient), browser_context_(new content::TestBrowserContext), extensions_browser_client_( new TestExtensionsBrowserClient(browser_context_.get())) { content::SetContentClient(content_client_.get()); + content::SetUtilityClientForTesting(content_utility_client_.get()); content::SetBrowserClientForTesting(content_browser_client_.get()); ExtensionsBrowserClient::Set(extensions_browser_client_.get()); } @@ -34,6 +37,7 @@ ExtensionsTest::ExtensionsTest() ExtensionsTest::~ExtensionsTest() { ExtensionsBrowserClient::Set(NULL); content::SetBrowserClientForTesting(NULL); + content::SetUtilityClientForTesting(NULL); content::SetContentClient(NULL); } diff --git a/extensions/browser/extensions_test.h b/extensions/browser/extensions_test.h index 3f5dd0a..ef71aee 100644 --- a/extensions/browser/extensions_test.h +++ b/extensions/browser/extensions_test.h @@ -12,8 +12,9 @@ namespace content { class BrowserContext; -class ContentClient; class ContentBrowserClient; +class ContentClient; +class ContentUtilityClient; } namespace extensions { @@ -49,6 +50,7 @@ class ExtensionsTest : public testing::Test { private: // TODO(yoz): Add a NotificationService here; it's used widely enough. scoped_ptr<content::ContentClient> content_client_; + scoped_ptr<content::ContentUtilityClient> content_utility_client_; scoped_ptr<content::ContentBrowserClient> content_browser_client_; scoped_ptr<content::BrowserContext> browser_context_; scoped_ptr<TestExtensionsBrowserClient> extensions_browser_client_; diff --git a/chrome/browser/extensions/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index f01e584..cd535a8 100644 --- a/chrome/browser/extensions/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/extensions/sandboxed_unpacker.h" +#include "extensions/browser/sandboxed_unpacker.h" #include <set> @@ -20,12 +20,6 @@ #include "base/sequenced_task_runner.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/sequenced_worker_pool.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/chrome_utility_messages.h" -#include "chrome/common/extensions/chrome_utility_extensions_messages.h" -#include "chrome/grit/generated_resources.h" #include "components/crx_file/constants.h" #include "components/crx_file/crx_file.h" #include "components/crx_file/id_util.h" @@ -41,6 +35,7 @@ #include "extensions/common/file_util.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/icons_handler.h" +#include "grit/extensions_strings.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/codec/png_codec.h" @@ -57,19 +52,18 @@ using crx_file::CrxFile; // fail to install. To see if this is happening, see how long the // path to the temp unpack directory is. See crbug.com/69693 . #define PATH_LENGTH_HISTOGRAM(name, path) \ - UMA_HISTOGRAM_CUSTOM_COUNTS(name, path.value().length(), 0, 500, 100) + UMA_HISTOGRAM_CUSTOM_COUNTS(name, path.value().length(), 0, 500, 100) // Record a rate (kB per second) at which extensions are unpacked. // Range from 1kB/s to 100mB/s. #define UNPACK_RATE_HISTOGRAM(name, rate) \ - UMA_HISTOGRAM_CUSTOM_COUNTS(name, rate, 1, 100000, 100); + UMA_HISTOGRAM_CUSTOM_COUNTS(name, rate, 1, 100000, 100); namespace extensions { namespace { -void RecordSuccessfulUnpackTimeHistograms( - const base::FilePath& crx_path, const base::TimeDelta unpack_time) { - +void RecordSuccessfulUnpackTimeHistograms(const base::FilePath& crx_path, + const base::TimeDelta unpack_time) { const int64 kBytesPerKb = 1024; const int64 kBytesPerMb = 1024 * 1024; @@ -86,8 +80,8 @@ void RecordSuccessfulUnpackTimeHistograms( // Cast is safe as long as the number of bytes in the CRX is less than // 2^31 * 2^10. int crx_file_size_kb = static_cast<int>(crx_file_size / kBytesPerKb); - UMA_HISTOGRAM_COUNTS( - "Extensions.SandboxUnpackSuccessCrxSize", crx_file_size_kb); + UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccessCrxSize", + crx_file_size_kb); // We have time in seconds and file size in bytes. We want the rate bytes are // unpacked in kB/s. @@ -98,28 +92,28 @@ void RecordSuccessfulUnpackTimeHistograms( UNPACK_RATE_HISTOGRAM("Extensions.SandboxUnpackRate", unpack_rate_kb_per_s); if (crx_file_size < 50.0 * kBytesPerKb) { - UNPACK_RATE_HISTOGRAM( - "Extensions.SandboxUnpackRateUnder50kB", unpack_rate_kb_per_s); + UNPACK_RATE_HISTOGRAM("Extensions.SandboxUnpackRateUnder50kB", + unpack_rate_kb_per_s); } else if (crx_file_size < 1 * kBytesPerMb) { - UNPACK_RATE_HISTOGRAM( - "Extensions.SandboxUnpackRate50kBTo1mB", unpack_rate_kb_per_s); + UNPACK_RATE_HISTOGRAM("Extensions.SandboxUnpackRate50kBTo1mB", + unpack_rate_kb_per_s); } else if (crx_file_size < 2 * kBytesPerMb) { - UNPACK_RATE_HISTOGRAM( - "Extensions.SandboxUnpackRate1To2mB", unpack_rate_kb_per_s); + UNPACK_RATE_HISTOGRAM("Extensions.SandboxUnpackRate1To2mB", + unpack_rate_kb_per_s); } else if (crx_file_size < 5 * kBytesPerMb) { - UNPACK_RATE_HISTOGRAM( - "Extensions.SandboxUnpackRate2To5mB", unpack_rate_kb_per_s); + UNPACK_RATE_HISTOGRAM("Extensions.SandboxUnpackRate2To5mB", + unpack_rate_kb_per_s); } else if (crx_file_size < 10 * kBytesPerMb) { - UNPACK_RATE_HISTOGRAM( - "Extensions.SandboxUnpackRate5To10mB", unpack_rate_kb_per_s); + UNPACK_RATE_HISTOGRAM("Extensions.SandboxUnpackRate5To10mB", + unpack_rate_kb_per_s); } else { - UNPACK_RATE_HISTOGRAM( - "Extensions.SandboxUnpackRateOver10mB", unpack_rate_kb_per_s); + UNPACK_RATE_HISTOGRAM("Extensions.SandboxUnpackRateOver10mB", + unpack_rate_kb_per_s); } } @@ -186,8 +180,7 @@ bool FindWritableTempLocation(const base::FilePath& extensions_dir, // data. Returns true on success. bool ReadImagesFromFile(const base::FilePath& extension_path, DecodedImages* images) { - base::FilePath path = - extension_path.AppendASCII(kDecodedImagesFilename); + base::FilePath path = extension_path.AppendASCII(kDecodedImagesFilename); std::string file_str; if (!base::ReadFileToString(path, &file_str)) return false; @@ -202,8 +195,8 @@ bool ReadImagesFromFile(const base::FilePath& extension_path, // data. Returns true on success. bool ReadMessageCatalogsFromFile(const base::FilePath& extension_path, base::DictionaryValue* catalogs) { - base::FilePath path = extension_path.AppendASCII( - kDecodedMessageCatalogsFilename); + base::FilePath path = + extension_path.AppendASCII(kDecodedMessageCatalogsFilename); std::string file_str; if (!base::ReadFileToString(path, &file_str)) return false; @@ -236,20 +229,18 @@ bool SandboxedUnpacker::CreateTempDirectory() { base::FilePath temp_dir; if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) { - ReportFailure( - COULD_NOT_GET_TEMP_DIRECTORY, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"))); + ReportFailure(COULD_NOT_GET_TEMP_DIRECTORY, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"))); return false; } if (!temp_dir_.CreateUniqueTempDirUnderPath(temp_dir)) { - ReportFailure( - COULD_NOT_CREATE_TEMP_DIRECTORY, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY"))); + ReportFailure(COULD_NOT_CREATE_TEMP_DIRECTORY, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY"))); return false; } @@ -301,20 +292,16 @@ void SandboxedUnpacker::Start() { if (!base::NormalizeFilePath(temp_crx_path, &link_free_crx_path)) { LOG(ERROR) << "Could not get the normalized path of " << temp_crx_path.value(); - ReportFailure( - COULD_NOT_GET_SANDBOX_FRIENDLY_PATH, - l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED)); + ReportFailure(COULD_NOT_GET_SANDBOX_FRIENDLY_PATH, + l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED)); return; } PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength", link_free_crx_path); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind( - &SandboxedUnpacker::StartProcessOnIOThread, - this, - link_free_crx_path)); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&SandboxedUnpacker::StartProcessOnIOThread, + this, link_free_crx_path)); } SandboxedUnpacker::~SandboxedUnpacker() { @@ -323,11 +310,11 @@ SandboxedUnpacker::~SandboxedUnpacker() { bool SandboxedUnpacker::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(SandboxedUnpacker, message) - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_UnpackExtension_Succeeded, - OnUnpackExtensionSucceeded) - IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_UnpackExtension_Failed, - OnUnpackExtensionFailed) - IPC_MESSAGE_UNHANDLED(handled = false) + IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_UnpackExtension_Succeeded, + OnUnpackExtensionSucceeded) + IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_UnpackExtension_Failed, + OnUnpackExtensionFailed) + IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; } @@ -339,12 +326,12 @@ void SandboxedUnpacker::OnProcessCrashed(int exit_code) { // Utility process crashed while trying to install. ReportFailure( - UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) + - ASCIIToUTF16(". ") + - l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)); + UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) + + ASCIIToUTF16(". ") + + l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)); } void SandboxedUnpacker::StartProcessOnIOThread( @@ -354,9 +341,8 @@ void SandboxedUnpacker::StartProcessOnIOThread( // Grant the subprocess access to the entire subdir the extension file is // in, so that it can unpack to that dir. host->SetExposedDir(temp_crx_path.DirName()); - host->Send( - new ChromeUtilityMsg_UnpackExtension( - temp_crx_path, extension_id_, location_, creation_flags_)); + host->Send(new ChromeUtilityMsg_UnpackExtension(temp_crx_path, extension_id_, + location_, creation_flags_)); } void SandboxedUnpacker::OnUnpackExtensionSucceeded( @@ -379,23 +365,18 @@ void SandboxedUnpacker::OnUnpackExtensionSucceeded( // TODO(rdevlin.cronin): Continue removing std::string errors and replacing // with base::string16 std::string utf8_error; - if (!extension_l10n_util::LocalizeExtension(extension_root_, - final_manifest.get(), - &utf8_error)) { + if (!extension_l10n_util::LocalizeExtension( + extension_root_, final_manifest.get(), &utf8_error)) { ReportFailure( COULD_NOT_LOCALIZE_EXTENSION, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, - base::UTF8ToUTF16(utf8_error))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, + base::UTF8ToUTF16(utf8_error))); return; } - extension_ = Extension::Create( - extension_root_, - location_, - *final_manifest, - Extension::REQUIRE_KEY | creation_flags_, - &utf8_error); + extension_ = + Extension::Create(extension_root_, location_, *final_manifest, + Extension::REQUIRE_KEY | creation_flags_, &utf8_error); if (!extension_.get()) { ReportFailure(INVALID_MANIFEST, @@ -418,17 +399,15 @@ void SandboxedUnpacker::OnUnpackExtensionFailed(const base::string16& error) { got_response_ = true; ReportFailure( UNPACKER_CLIENT_FAILED, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, - error)); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error)); } bool SandboxedUnpacker::ValidateSignature() { base::ScopedFILE file(base::OpenFile(crx_path_, "rb")); if (!file.get()) { - // Could not open crx file for reading. -#if defined (OS_WIN) +// Could not open crx file for reading. +#if defined(OS_WIN) // On windows, get the error code. uint32 error_code = ::GetLastError(); // TODO(skerner): Use this histogram to understand why so many @@ -441,15 +420,14 @@ bool SandboxedUnpacker::ValidateSignature() { // the range. const uint32 kMaxErrorToSend = 1001; error_code = std::min(error_code, kMaxErrorToSend); - UMA_HISTOGRAM_ENUMERATION("Extensions.ErrorCodeFromCrxOpen", - error_code, kMaxErrorToSend); + UMA_HISTOGRAM_ENUMERATION("Extensions.ErrorCodeFromCrxOpen", error_code, + kMaxErrorToSend); #endif ReportFailure( CRX_FILE_NOT_READABLE, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_FILE_NOT_READABLE"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_FILE_NOT_READABLE"))); return false; } @@ -462,11 +440,9 @@ bool SandboxedUnpacker::ValidateSignature() { size_t len = fread(&header, 1, sizeof(header), file.get()); if (len < sizeof(header)) { // Invalid crx header - ReportFailure( - CRX_HEADER_INVALID, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_HEADER_INVALID"))); + ReportFailure(CRX_HEADER_INVALID, l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_HEADER_INVALID"))); return false; } @@ -475,19 +451,17 @@ bool SandboxedUnpacker::ValidateSignature() { if (!crx) { switch (error) { case CrxFile::kWrongMagic: - ReportFailure( - CRX_MAGIC_NUMBER_INVALID, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID"))); + ReportFailure(CRX_MAGIC_NUMBER_INVALID, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID"))); break; case CrxFile::kInvalidVersion: // Bad version numer - ReportFailure( - CRX_VERSION_NUMBER_INVALID, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID"))); + ReportFailure(CRX_VERSION_NUMBER_INVALID, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID"))); break; case CrxFile::kInvalidKeyTooLarge: case CrxFile::kInvalidSignatureTooLarge: @@ -502,17 +476,15 @@ bool SandboxedUnpacker::ValidateSignature() { // Key length is zero ReportFailure( CRX_ZERO_KEY_LENGTH, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_ZERO_KEY_LENGTH"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_ZERO_KEY_LENGTH"))); break; case CrxFile::kInvalidSignatureTooSmall: // Signature length is zero - ReportFailure( - CRX_ZERO_SIGNATURE_LENGTH, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH"))); + ReportFailure(CRX_ZERO_SIGNATURE_LENGTH, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH"))); break; } return false; @@ -525,33 +497,28 @@ bool SandboxedUnpacker::ValidateSignature() { // Invalid public key ReportFailure( CRX_PUBLIC_KEY_INVALID, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID"))); return false; } std::vector<uint8> signature; signature.resize(header.signature_size); len = fread(&signature.front(), sizeof(uint8), header.signature_size, - file.get()); + file.get()); if (len < header.signature_size) { // Invalid signature ReportFailure( CRX_SIGNATURE_INVALID, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_SIGNATURE_INVALID"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_SIGNATURE_INVALID"))); return false; } crypto::SignatureVerifier verifier; - if (!verifier.VerifyInit(crx_file::kSignatureAlgorithm, - sizeof(crx_file::kSignatureAlgorithm), - &signature.front(), - signature.size(), - &key.front(), - key.size())) { + if (!verifier.VerifyInit( + crx_file::kSignatureAlgorithm, sizeof(crx_file::kSignatureAlgorithm), + &signature.front(), signature.size(), &key.front(), key.size())) { // Signature verification initialization failed. This is most likely // caused by a public key in the wrong format (should encode algorithm). ReportFailure( @@ -568,11 +535,10 @@ bool SandboxedUnpacker::ValidateSignature() { if (!verifier.VerifyFinal()) { // Signature verification failed - ReportFailure( - CRX_SIGNATURE_VERIFICATION_FAILED, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_ERROR_CODE, - ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED"))); + ReportFailure(CRX_SIGNATURE_VERIFICATION_FAILED, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED"))); return false; } @@ -587,8 +553,8 @@ bool SandboxedUnpacker::ValidateSignature() { void SandboxedUnpacker::ReportFailure(FailureReason reason, const base::string16& error) { - UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", - reason, NUM_FAILURE_REASONS); + UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason, + NUM_FAILURE_REASONS); UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", base::TimeTicks::Now() - unpack_start_time_); Cleanup(); @@ -604,9 +570,8 @@ void SandboxedUnpacker::ReportSuccess( crx_path_, base::TimeTicks::Now() - unpack_start_time_); // Client takes ownership of temporary directory and extension. - client_->OnUnpackSuccess( - temp_dir_.Take(), extension_root_, &original_manifest, extension_.get(), - install_icon); + client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_, + &original_manifest, extension_.get(), install_icon); extension_ = NULL; } @@ -623,24 +588,21 @@ base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile( serializer.set_pretty_print(true); if (!serializer.Serialize(*final_manifest)) { // Error serializing manifest.json. - ReportFailure( - ERROR_SERIALIZING_MANIFEST_JSON, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON"))); + ReportFailure(ERROR_SERIALIZING_MANIFEST_JSON, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON"))); return NULL; } - base::FilePath manifest_path = - extension_root_.Append(kManifestFilename); + base::FilePath manifest_path = extension_root_.Append(kManifestFilename); int size = base::checked_cast<int>(manifest_json.size()); if (base::WriteFile(manifest_path, manifest_json.data(), size) != size) { // Error saving manifest.json. ReportFailure( ERROR_SAVING_MANIFEST_JSON, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON"))); return NULL; } @@ -651,11 +613,10 @@ bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { DecodedImages images; if (!ReadImagesFromFile(temp_dir_.path(), &images)) { // Couldn't read image data from disk. - ReportFailure( - COULD_NOT_READ_IMAGE_DATA_FROM_DISK, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK"))); + ReportFailure(COULD_NOT_READ_IMAGE_DATA_FROM_DISK, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK"))); return false; } @@ -679,27 +640,26 @@ bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { base::FilePath path = *it; if (path.IsAbsolute() || path.ReferencesParent()) { // Invalid path for browser image. - ReportFailure( - INVALID_PATH_FOR_BROWSER_IMAGE, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE"))); + ReportFailure(INVALID_PATH_FOR_BROWSER_IMAGE, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE"))); return false; } if (!base::DeleteFile(extension_root_.Append(path), false)) { // Error removing old image file. - ReportFailure( - ERROR_REMOVING_OLD_IMAGE_FILE, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE"))); + ReportFailure(ERROR_REMOVING_OLD_IMAGE_FILE, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE"))); return false; } } const std::string& install_icon_path = - IconsInfo::GetIcons(extension_.get()).Get( - extension_misc::EXTENSION_ICON_LARGE, ExtensionIconSet::MATCH_BIGGER); + IconsInfo::GetIcons(extension_.get()) + .Get(extension_misc::EXTENSION_ICON_LARGE, + ExtensionIconSet::MATCH_BIGGER); // Write our parsed images back to disk as well. for (size_t i = 0; i < images.size(); ++i) { @@ -707,9 +667,8 @@ bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { // Abort package installation if shutdown was initiated, crbug.com/235525 ReportFailure( ABORTED_DUE_TO_SHUTDOWN, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ABORTED_DUE_TO_SHUTDOWN"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ABORTED_DUE_TO_SHUTDOWN"))); return false; } @@ -720,11 +679,10 @@ bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { if (path_suffix.IsAbsolute() || path_suffix.ReferencesParent()) { // Invalid path for bitmap image. - ReportFailure( - INVALID_PATH_FOR_BITMAP_IMAGE, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE"))); + ReportFailure(INVALID_PATH_FOR_BITMAP_IMAGE, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE"))); return false; } base::FilePath path = extension_root_.Append(path_suffix); @@ -735,11 +693,10 @@ bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { // http://code.google.com/p/chromium/issues/detail?id=12459 if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data)) { // Error re-encoding theme image. - ReportFailure( - ERROR_RE_ENCODING_THEME_IMAGE, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE"))); + ReportFailure(ERROR_RE_ENCODING_THEME_IMAGE, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE"))); return false; } @@ -751,9 +708,8 @@ bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { // Error saving theme image. ReportFailure( ERROR_SAVING_THEME_IMAGE, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); return false; } } @@ -765,25 +721,23 @@ bool SandboxedUnpacker::RewriteCatalogFiles() { base::DictionaryValue catalogs; if (!ReadMessageCatalogsFromFile(temp_dir_.path(), &catalogs)) { // Could not read catalog data from disk. - ReportFailure( - COULD_NOT_READ_CATALOG_DATA_FROM_DISK, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); + ReportFailure(COULD_NOT_READ_CATALOG_DATA_FROM_DISK, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); return false; } // Write our parsed catalogs back to disk. - for (base::DictionaryValue::Iterator it(catalogs); - !it.IsAtEnd(); it.Advance()) { + for (base::DictionaryValue::Iterator it(catalogs); !it.IsAtEnd(); + it.Advance()) { const base::DictionaryValue* catalog = NULL; if (!it.value().GetAsDictionary(&catalog)) { // Invalid catalog data. ReportFailure( INVALID_CATALOG_DATA, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("INVALID_CATALOG_DATA"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("INVALID_CATALOG_DATA"))); return false; } @@ -793,9 +747,8 @@ bool SandboxedUnpacker::RewriteCatalogFiles() { // Invalid path for catalog. ReportFailure( INVALID_PATH_FOR_CATALOG, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("INVALID_PATH_FOR_CATALOG"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("INVALID_PATH_FOR_CATALOG"))); return false; } base::FilePath path = extension_root_.Append(relative_path); @@ -805,11 +758,10 @@ bool SandboxedUnpacker::RewriteCatalogFiles() { serializer.set_pretty_print(true); if (!serializer.Serialize(*catalog)) { // Error serializing catalog. - ReportFailure( - ERROR_SERIALIZING_CATALOG, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ERROR_SERIALIZING_CATALOG"))); + ReportFailure(ERROR_SERIALIZING_CATALOG, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ERROR_SERIALIZING_CATALOG"))); return false; } @@ -820,9 +772,8 @@ bool SandboxedUnpacker::RewriteCatalogFiles() { // Error saving catalog. ReportFailure( ERROR_SAVING_CATALOG, - l10n_util::GetStringFUTF16( - IDS_EXTENSION_PACKAGE_INSTALL_ERROR, - ASCIIToUTF16("ERROR_SAVING_CATALOG"))); + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, + ASCIIToUTF16("ERROR_SAVING_CATALOG"))); return false; } } diff --git a/chrome/browser/extensions/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h index 60a5bbd..60a5bbd 100644 --- a/chrome/browser/extensions/sandboxed_unpacker.h +++ b/extensions/browser/sandboxed_unpacker.h diff --git a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc b/extensions/browser/sandboxed_unpacker_unittest.cc index 4d46e7c..7451b28 100644 --- a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc +++ b/extensions/browser/sandboxed_unpacker_unittest.cc @@ -10,10 +10,10 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/values.h" -#include "chrome/browser/extensions/sandboxed_unpacker.h" -#include "chrome/common/chrome_paths.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" +#include "extensions/browser/extensions_test.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/extension_paths.h" @@ -24,7 +24,6 @@ namespace extensions { class MockSandboxedUnpackerClient : public SandboxedUnpackerClient { public: - void WaitForUnpack() { scoped_refptr<content::MessageLoopRunner> runner = new content::MessageLoopRunner; @@ -44,7 +43,6 @@ class MockSandboxedUnpackerClient : public SandboxedUnpackerClient { const SkBitmap& install_icon) override { temp_dir_ = temp_dir; quit_closure_.Run(); - } void OnUnpackFailure(const base::string16& error) override { @@ -55,10 +53,11 @@ class MockSandboxedUnpackerClient : public SandboxedUnpackerClient { base::FilePath temp_dir_; }; -class SandboxedUnpackerTest : public testing::Test { +class SandboxedUnpackerTest : public ExtensionsTest { public: void SetUp() override { - ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir()); + ExtensionsTest::SetUp(); + ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir()); browser_threads_.reset(new content::TestBrowserThreadBundle( content::TestBrowserThreadBundle::IO_MAINLOOP)); in_process_utility_thread_helper_.reset( @@ -72,6 +71,7 @@ class SandboxedUnpackerTest : public testing::Test { // it posts a task to it. sandboxed_unpacker_ = NULL; base::RunLoop().RunUntilIdle(); + ExtensionsTest::TearDown(); } void SetupUnpacker(const std::string& crx_name) { @@ -81,12 +81,8 @@ class SandboxedUnpackerTest : public testing::Test { ASSERT_TRUE(base::PathExists(original_path)) << original_path.value(); sandboxed_unpacker_ = new SandboxedUnpacker( - original_path, - Manifest::INTERNAL, - Extension::NO_FLAGS, - extensions_dir_.path(), - base::MessageLoopProxy::current(), - client_); + original_path, Manifest::INTERNAL, Extension::NO_FLAGS, + extensions_dir_.path(), base::MessageLoopProxy::current(), client_); base::MessageLoopProxy::current()->PostTask( FROM_HERE, @@ -110,16 +106,14 @@ class SandboxedUnpackerTest : public testing::Test { TEST_F(SandboxedUnpackerTest, NoCatalogsSuccess) { SetupUnpacker("no_l10n.crx"); // Check that there is no _locales folder. - base::FilePath install_path = - GetInstallPath().Append(kLocaleFolder); + base::FilePath install_path = GetInstallPath().Append(kLocaleFolder); EXPECT_FALSE(base::PathExists(install_path)); } TEST_F(SandboxedUnpackerTest, WithCatalogsSuccess) { SetupUnpacker("good_l10n.crx"); // Check that there is _locales folder. - base::FilePath install_path = - GetInstallPath().Append(kLocaleFolder); + base::FilePath install_path = GetInstallPath().Append(kLocaleFolder); EXPECT_TRUE(base::PathExists(install_path)); } diff --git a/extensions/common/extension_utility_messages.h b/extensions/common/extension_utility_messages.h index 123fc98..35e37a3 100644 --- a/extensions/common/extension_utility_messages.h +++ b/extensions/common/extension_utility_messages.h @@ -41,6 +41,14 @@ IPC_STRUCT_TRAITS_END() IPC_MESSAGE_CONTROL1(ExtensionUtilityMsg_ParseUpdateManifest, std::string /* xml document contents */) +// Tells the utility process to unpack the given extension file in its +// directory and verify that it is valid. +IPC_MESSAGE_CONTROL4(ChromeUtilityMsg_UnpackExtension, + base::FilePath /* extension_filename */, + std::string /* extension_id */, + int /* Manifest::Location */, + int /* InitFromValue flags */) + //------------------------------------------------------------------------------ // Utility process host messages: // These are messages from the utility process to the browser. @@ -54,3 +62,18 @@ IPC_MESSAGE_CONTROL1(ExtensionUtilityHostMsg_ParseUpdateManifest_Succeeded, // is a description of what went wrong suitable for logging. IPC_MESSAGE_CONTROL1(ExtensionUtilityHostMsg_ParseUpdateManifest_Failed, std::string /* error_message, if any */) + +// Reply when the utility process is done unpacking an extension. |manifest| +// is the parsed manifest.json file. +// The unpacker should also have written out files containing the decoded +// images and message catalogs from the extension. The data is written into a +// DecodedImages struct into a file named kDecodedImagesFilename in the +// directory that was passed in. This is done because the data is too large to +// pass over IPC. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_UnpackExtension_Succeeded, + base::DictionaryValue /* manifest */) + +// Reply when the utility process has failed while unpacking an extension. +// |error_message| is a user-displayable explanation of what went wrong. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_UnpackExtension_Failed, + base::string16 /* error_message, if any */) diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index 0977c5d..9b7bfbb 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp @@ -795,6 +795,8 @@ 'browser/renderer_startup_helper.h', 'browser/runtime_data.cc', 'browser/runtime_data.h', + 'browser/sandboxed_unpacker.cc', + 'browser/sandboxed_unpacker.h', 'browser/script_execution_observer.h', 'browser/script_executor.cc', 'browser/script_executor.h', @@ -1110,7 +1112,7 @@ 'browser/guest_view/test_guest_view_manager.cc', 'browser/guest_view/test_guest_view_manager.h', 'browser/mock_extension_system.cc', - 'browser/mock_extension_system.h', + 'browser/mock_extension_system.h', 'browser/test_extension_registry_observer.cc', 'browser/test_extension_registry_observer.h', 'browser/test_extensions_browser_client.cc', @@ -1133,6 +1135,8 @@ 'test/extension_test_message_listener.h', 'test/result_catcher.cc', 'test/result_catcher.h', + 'test/test_content_utility_client.cc', + 'test/test_content_utility_client.h', 'test/test_extensions_client.cc', 'test/test_extensions_client.h', 'test/test_permission_message_provider.cc', diff --git a/extensions/extensions_strings.grd b/extensions/extensions_strings.grd index e4ab2c4..b15ed35 100644 --- a/extensions/extensions_strings.grd +++ b/extensions/extensions_strings.grd @@ -440,6 +440,29 @@ Communicate with cooperating websites </message> + <!-- Install related messages. Please keep alphabetized. --> + <message name="IDS_EXTENSION_INSTALL_PROCESS_CRASHED" desc="Error message in case package fails to install because a utility process crashed."> + Could not install package because a utility process crashed. Try restarting Chrome and trying again. + </message> + <message name="IDS_EXTENSION_PACKAGE_ERROR_CODE" desc="Error message in cases where we fail to install the extension because the crx file is invalid. For example, because the crx header or signature is invalid."> + Package is invalid: '<ph name="ERROR_CODE">$1<ex>error</ex></ph>'. + </message> + <message name="IDS_EXTENSION_PACKAGE_ERROR_MESSAGE" desc="The cases where we get an error message string back from some other component. The message might be in English, but these are typically developer errors, and the extension SDK is English."> + Package is invalid. Details: '<ph name="ERROR_MESSAGE">$1<ex>error</ex></ph>'. + </message> + <message name="IDS_EXTENSION_PACKAGE_INSTALL_ERROR" desc="Error message in case package fails to install because of some problem with the filesystem."> + Could not install package: '<ph name="ERROR_CODE">$1<ex>error</ex></ph>' + </message> + <if expr="is_win"> + <message name="IDS_EXTENSION_UNPACK_FAILED" desc="On windows, it is possible to mount a disk without the root of that disk having a drive letter. The sandbox does not support this. See crbug/49530 ."> + Can not unpack extension. To safely unpack an extension, there must be a path to your profile directory that starts with a drive letter and does not contain a junction, mount point, or symlink. No such path exists for your profile. + </message> + </if> + <if expr="not is_win"> + <message name="IDS_EXTENSION_UNPACK_FAILED" desc=""> + Can not unpack extension. To safely unpack an extension, there must be a path to your profile directory that does not contain a symlink. No such path exists for your profile. + </message> + </if> </messages> </release> </grit> diff --git a/extensions/extensions_tests.gyp b/extensions/extensions_tests.gyp index 0f47938..b1f8e85 100644 --- a/extensions/extensions_tests.gyp +++ b/extensions/extensions_tests.gyp @@ -90,6 +90,7 @@ 'browser/process_map_unittest.cc', 'browser/quota_service_unittest.cc', 'browser/runtime_data_unittest.cc', + 'browser/sandboxed_unpacker_unittest.cc', 'browser/value_store/leveldb_value_store_unittest.cc', 'browser/value_store/testing_value_store_unittest.cc', 'browser/value_store/value_store_change_unittest.cc', diff --git a/extensions/test/extensions_unittests_main.cc b/extensions/test/extensions_unittests_main.cc index 9452f31b..6fde7a3 100644 --- a/extensions/test/extensions_unittests_main.cc +++ b/extensions/test/extensions_unittests_main.cc @@ -74,6 +74,7 @@ void ExtensionsTestSuite::Initialize() { ExtensionsContentClient content_client; RegisterContentSchemes(&content_client); } + RegisterInProcessThreads(); extensions::RegisterPathProvider(); diff --git a/extensions/test/test_content_utility_client.cc b/extensions/test/test_content_utility_client.cc new file mode 100644 index 0000000..93f907e --- /dev/null +++ b/extensions/test/test_content_utility_client.cc @@ -0,0 +1,24 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/test/test_content_utility_client.h" + +namespace extensions { + +TestContentUtilityClient::TestContentUtilityClient() { +} + +TestContentUtilityClient::~TestContentUtilityClient() { +} + +void TestContentUtilityClient::UtilityThreadStarted() { + UtilityHandler::UtilityThreadStarted(); +} + +bool TestContentUtilityClient::OnMessageReceived(const IPC::Message& message) { + return utility_handler_.OnMessageReceived(message); +} + + +} // namespace extensions diff --git a/extensions/test/test_content_utility_client.h b/extensions/test/test_content_utility_client.h new file mode 100644 index 0000000..518806a --- /dev/null +++ b/extensions/test/test_content_utility_client.h @@ -0,0 +1,28 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_TEST_TEST_CONTENT_UTILITY_CLIENT_H_ +#define EXTENSIONS_TEST_TEST_CONTENT_UTILITY_CLIENT_H_ + +#include "content/public/utility/content_utility_client.h" +#include "extensions/utility/utility_handler.h" + +namespace extensions { + +class TestContentUtilityClient : public content::ContentUtilityClient { + public: + TestContentUtilityClient(); + ~TestContentUtilityClient() override; + + // ContentUtilityClient implementation + void UtilityThreadStarted() override; + bool OnMessageReceived(const IPC::Message& message) override; + + private: + UtilityHandler utility_handler_; +}; + +} // namespace extensions + +#endif // EXTENSIONS_TEST_TEST_CONTENT_UTILITY_CLIENT_H_ diff --git a/extensions/utility/utility_handler.cc b/extensions/utility/utility_handler.cc index 1298933..3add93e 100644 --- a/extensions/utility/utility_handler.cc +++ b/extensions/utility/utility_handler.cc @@ -5,11 +5,15 @@ #include "extensions/utility/utility_handler.h" #include "base/command_line.h" +#include "base/files/file_path.h" #include "content/public/utility/utility_thread.h" #include "extensions/common/extension.h" #include "extensions/common/extension_l10n_util.h" #include "extensions/common/extension_utility_messages.h" +#include "extensions/common/extensions_client.h" +#include "extensions/common/manifest.h" #include "extensions/common/update_manifest.h" +#include "extensions/utility/unpacker.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" #include "ui/base/ui_base_switches.h" @@ -45,6 +49,7 @@ void UtilityHandler::UtilityThreadStarted() { bool UtilityHandler::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(UtilityHandler, message) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnpackExtension, OnUnpackExtension) IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_ParseUpdateManifest, OnParseUpdateManifest) IPC_MESSAGE_UNHANDLED(handled = false) @@ -64,4 +69,29 @@ void UtilityHandler::OnParseUpdateManifest(const std::string& xml) { ReleaseProcessIfNeeded(); } +void UtilityHandler::OnUnpackExtension( + const base::FilePath& extension_path, + const std::string& extension_id, + int location, + int creation_flags) { + CHECK_GT(location, Manifest::INVALID_LOCATION); + CHECK_LT(location, Manifest::NUM_LOCATIONS); + DCHECK(ExtensionsClient::Get()); + Unpacker unpacker(extension_path, + extension_id, + static_cast<Manifest::Location>(location), + creation_flags); + if (unpacker.Run() && unpacker.DumpImagesToFile() && + unpacker.DumpMessageCatalogsToFile()) { + Send(new ChromeUtilityHostMsg_UnpackExtension_Succeeded( + *unpacker.parsed_manifest())); + } else { + Send(new ChromeUtilityHostMsg_UnpackExtension_Failed( + unpacker.error_message())); + } + + ReleaseProcessIfNeeded(); +} + + } // namespace extensions diff --git a/extensions/utility/utility_handler.h b/extensions/utility/utility_handler.h index 0ae31ec..89a81d6 100644 --- a/extensions/utility/utility_handler.h +++ b/extensions/utility/utility_handler.h @@ -7,8 +7,13 @@ #include <string> +#include "base/callback.h" #include "base/macros.h" +namespace base { +class FilePath; +} + namespace IPC { class Message; } @@ -28,6 +33,9 @@ class UtilityHandler { private: // IPC message handlers. void OnParseUpdateManifest(const std::string& xml); + void OnUnpackExtension(const base::FilePath& extension_path, + const std::string& extension_id, + int location, int creation_flags); DISALLOW_COPY_AND_ASSIGN(UtilityHandler); }; diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ea69ba7..6b9188a 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -8999,6 +8999,11 @@ Therefore, the affected-histogram name has to have at least one dot in it. </summary> </histogram> +<histogram name="Extensions.SandboxUnpackSuccessCrxSize"> + <owner>asargent@chromium.org</owner> + <summary>Size of the .crx file, in KB, when the unpack succeeds.</summary> +</histogram> + <histogram name="Extensions.SandboxUnpackSuccessTime"> <owner>asargent@chromium.org</owner> <summary> |