diff options
Diffstat (limited to 'chromium/ui/base/resource')
-rw-r--r-- | chromium/ui/base/resource/data_pack.cc | 23 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle.cc | 53 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle.h | 24 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle_android.cc | 38 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle_android.h | 42 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle_ios.mm | 11 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle_mac.mm | 12 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle_unittest.cc | 8 | ||||
-rw-r--r-- | chromium/ui/base/resource/resource_bundle_win.h | 6 |
9 files changed, 128 insertions, 89 deletions
diff --git a/chromium/ui/base/resource/data_pack.cc b/chromium/ui/base/resource/data_pack.cc index 618204dfcda..09513e6aed2 100644 --- a/chromium/ui/base/resource/data_pack.cc +++ b/chromium/ui/base/resource/data_pack.cc @@ -10,6 +10,7 @@ #include <utility> #include "base/command_line.h" +#include "base/files/file.h" #include "base/files/file_util.h" #include "base/files/memory_mapped_file.h" #include "base/logging.h" @@ -41,8 +42,11 @@ static const size_t kHeaderLengthV5 = // We're crashing when trying to load a pak file on Windows. Add some error // codes for logging. // http://crbug.com/58056 +// These values are logged to UMA. Entries should not be renumbered and +// numeric values should never be reused. Keep in sync with "DataPackLoadErrors" +// in src/tools/metrics/histograms/enums.xml. enum LoadErrors { - INIT_FAILED = 1, + INIT_FAILED_OBSOLETE = 1, BAD_VERSION, INDEX_TRUNCATED, ENTRY_NOT_FOUND, @@ -50,6 +54,8 @@ enum LoadErrors { WRONG_ENCODING, INIT_FAILED_FROM_FILE, UNZIP_FAILED, + OPEN_FAILED, + MAP_FAILED, LOAD_ERRORS_COUNT, }; @@ -274,9 +280,20 @@ DataPack::~DataPack() { bool DataPack::LoadFromPath(const base::FilePath& path) { std::unique_ptr<base::MemoryMappedFile> mmap = std::make_unique<base::MemoryMappedFile>(); - if (!mmap->Initialize(path)) { + // Open the file for reading; allowing other consumers to also open it for + // reading and deleting. Do not allow others to write to it. + base::File data_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_EXCLUSIVE_WRITE | + base::File::FLAG_SHARE_DELETE); + if (!data_file.IsValid()) { + DLOG(ERROR) << "Failed to open datapack with base::File::Error " + << data_file.error_details(); + LogDataPackError(OPEN_FAILED); + return false; + } + if (!mmap->Initialize(std::move(data_file))) { DLOG(ERROR) << "Failed to mmap datapack"; - LogDataPackError(INIT_FAILED); + LogDataPackError(MAP_FAILED); return false; } if (MmapHasGzipHeader(mmap.get())) { diff --git a/chromium/ui/base/resource/resource_bundle.cc b/chromium/ui/base/resource/resource_bundle.cc index 133540ca848..eeb09546b45 100644 --- a/chromium/ui/base/resource/resource_bundle.cc +++ b/chromium/ui/base/resource/resource_bundle.cc @@ -12,10 +12,12 @@ #include "base/big_endian.h" #include "base/command_line.h" +#include "base/debug/alias.h" #include "base/files/file.h" #include "base/files/file_util.h" #include "base/logging.h" #include "base/memory/ref_counted_memory.h" +#include "base/notreached.h" #include "base/path_service.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" @@ -45,6 +47,7 @@ #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_source.h" #include "ui/strings/grit/app_locale_settings.h" +#include "url/gurl.h" #if defined(OS_ANDROID) #include "base/android/build_info.h" @@ -257,7 +260,9 @@ std::string ResourceBundle::InitSharedInstanceWithLocale( InitSharedInstance(delegate); if (load_resources == LOAD_COMMON_RESOURCES) g_shared_instance_->LoadCommonResources(); - std::string result = g_shared_instance_->LoadLocaleResources(pref_locale); + std::string result = + g_shared_instance_->LoadLocaleResources(pref_locale, + /*crash_on_failure=*/true); g_shared_instance_->InitDefaultFontList(); return result; } @@ -326,7 +331,8 @@ void ResourceBundle::LoadSecondaryLocaleDataWithPakFileRegion( #if !defined(OS_ANDROID) // static bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { - return !GetLocaleFilePath(locale).empty(); + const auto path = GetLocaleFilePath(locale); + return !path.empty() && base::PathExists(path); } #endif // !defined(OS_ANDROID) @@ -378,10 +384,7 @@ base::FilePath ResourceBundle::GetLocaleFilePath( return base::FilePath(); base::FilePath locale_file_path; - - base::PathService::Get(ui::DIR_LOCALES, &locale_file_path); - - if (!locale_file_path.empty()) { + if (base::PathService::Get(ui::DIR_LOCALES, &locale_file_path)) { #if defined(OS_ANDROID) if (locale_file_path.value().find("chromium_tests") == std::string::npos) { std::string extracted_file_suffix = @@ -410,20 +413,14 @@ base::FilePath ResourceBundle::GetLocaleFilePath( locale_file_path, app_locale); } - // Don't try to load empty values or values that are not absolute paths. - if (locale_file_path.empty() || !locale_file_path.IsAbsolute()) - return base::FilePath(); - - if (base::PathExists(locale_file_path)) - return locale_file_path; - - return base::FilePath(); + // Don't try to load from paths that are not absolute. + return locale_file_path.IsAbsolute() ? locale_file_path : base::FilePath(); } #endif #if !defined(OS_ANDROID) -std::string ResourceBundle::LoadLocaleResources( - const std::string& pref_locale) { +std::string ResourceBundle::LoadLocaleResources(const std::string& pref_locale, + bool crash_on_failure) { DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); base::FilePath locale_file_path = GetOverriddenPakPath(); @@ -437,10 +434,18 @@ std::string ResourceBundle::LoadLocaleResources( } std::unique_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P)); - if (!data_pack->LoadFromPath(locale_file_path)) { - LOG(ERROR) << "failed to load locale file: " << locale_file_path; - NOTREACHED(); - return std::string(); + if (!data_pack->LoadFromPath(locale_file_path) && crash_on_failure) { + // https://crbug.com/1076423: Chrome can't start when the locale file cannot + // be loaded. Crash early and gather some data. +#if defined(OS_WIN) + const auto last_error = ::GetLastError(); + base::debug::Alias(&last_error); + wchar_t path_copy[MAX_PATH]; + base::wcslcpy(path_copy, locale_file_path.value().c_str(), + base::size(path_copy)); + base::debug::Alias(path_copy); +#endif // defined(OS_WIN) + CHECK(false); } locale_resources_data_ = std::move(data_pack); @@ -500,6 +505,12 @@ base::string16 ResourceBundle::MaybeMangleLocalizedString( if (base::StringToInt(str, &ignored)) return str; + // IDS_WEBSTORE_URL and some other resources are localization "strings" that + // are actually URLs, where the "localized" part is actually just the language + // code embedded in the URL. Don't mangle any URL. + if (GURL(str).is_valid()) + return str; + // For a string S, produce [[ --- S --- ]], where the number of dashes is 1/4 // of the number of characters in S. This makes S something around 50-75% // longer, except for extremely short strings, which get > 100% longer. @@ -518,7 +529,7 @@ std::string ResourceBundle::ReloadLocaleResources( overridden_locale_strings_.clear(); UnloadLocaleResources(); - return LoadLocaleResources(pref_locale); + return LoadLocaleResources(pref_locale, /*crash_on_failure=*/false); } gfx::ImageSkia* ResourceBundle::GetImageSkiaNamed(int resource_id) { diff --git a/chromium/ui/base/resource/resource_bundle.h b/chromium/ui/base/resource/resource_bundle.h index 0b62c5dba94..9cbc1d512ac 100644 --- a/chromium/ui/base/resource/resource_bundle.h +++ b/chromium/ui/base/resource/resource_bundle.h @@ -13,6 +13,7 @@ #include <unordered_map> #include <vector> +#include "base/component_export.h" #include "base/files/file_path.h" #include "base/files/memory_mapped_file.h" #include "base/gtest_prod_util.h" @@ -21,7 +22,6 @@ #include "base/strings/string16.h" #include "base/strings/string_piece.h" #include "ui/base/layout.h" -#include "ui/base/ui_base_export.h" #include "ui/gfx/font_list.h" #include "ui/gfx/image/image.h" #include "ui/gfx/native_widget_types.h" @@ -41,7 +41,7 @@ class ResourceHandle; // ResourceBundle is a central facility to load images and other resources, // such as theme graphics. Every resource is loaded only once. -class UI_BASE_EXPORT ResourceBundle { +class COMPONENT_EXPORT(UI_BASE) ResourceBundle { public: // Legacy font size deltas. Consider these to be magic numbers. New code // should declare their own size delta constant using an identifier that @@ -121,9 +121,10 @@ class UI_BASE_EXPORT ResourceBundle { // Initialize the ResourceBundle for this process. Does not take ownership of // the |delegate| value. Returns the language selected or an empty string if - // initialization failed (e.g. resource bundle not found or corrupted). - // NOTE: Mac ignores this and always loads up resources for the language - // defined by the Cocoa UI (i.e., NSBundle does the language work). + // no candidate bundle file could be determined, or crashes the process if a + // candidate could not be loaded (e.g., file not found or corrupted). NOTE: + // Mac ignores this and always loads up resources for the language defined by + // the Cocoa UI (i.e., NSBundle does the language work). // // TODO(sergeyu): This method also loads common resources (i.e. chrome.pak). // There is no way to specify which resource files are loaded, i.e. names of @@ -323,8 +324,10 @@ class UI_BASE_EXPORT ResourceBundle { const base::string16& string); // Returns the full pathname of the locale file to load, which may be a - // compressed locale file ending in .gz. Returns an empty string if no locale - // data files are found. + // compressed locale file ending in .gz. Returns an empty path if |app_locale| + // is empty, the directory of locale files cannot be determined, or if the + // path to the directory of locale files is relative. If not empty, the + // returned path is not guaranteed to reference an existing file. // Used on Android to load the local file in the browser process and pass it // to the sandboxed renderer process. static base::FilePath GetLocaleFilePath(const std::string& app_locale); @@ -396,8 +399,11 @@ class UI_BASE_EXPORT ResourceBundle { void AddDataPack(std::unique_ptr<DataPack> data_pack); // Try to load the locale specific strings from an external data module. - // Returns the locale that is loaded. - std::string LoadLocaleResources(const std::string& pref_locale); + // Returns the locale that is loaded or an empty string if no resources were + // loaded. If |crash_on_failure| is true on non-Android platforms, the process + // is terminated if a candidate locale file could not be loaded. + std::string LoadLocaleResources(const std::string& pref_locale, + bool crash_on_failure); // Load test resources in given paths. If either path is empty an empty // resource pack is loaded. diff --git a/chromium/ui/base/resource/resource_bundle_android.cc b/chromium/ui/base/resource/resource_bundle_android.cc index c86a3bfa2bd..e8cf7b78c66 100644 --- a/chromium/ui/base/resource/resource_bundle_android.cc +++ b/chromium/ui/base/resource/resource_bundle_android.cc @@ -4,10 +4,14 @@ #include "ui/base/resource/resource_bundle_android.h" +#include <utility> + #include "base/android/apk_assets.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" +#include "base/files/file_util.h" #include "base/logging.h" +#include "base/notreached.h" #include "base/path_service.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/data_pack.h" @@ -56,11 +60,10 @@ bool LoadFromApkOrFile(const char* apk_path, int LoadLocalePakFromApk(const std::string& app_locale, bool in_split, base::MemoryMappedFile::Region* out_region) { + bool log_error = true; std::string locale_path_within_apk = - GetPathForAndroidLocalePakWithinApk(app_locale, in_split); + GetPathForAndroidLocalePakWithinApk(app_locale, in_split, log_error); if (locale_path_within_apk.empty()) { - LOG(WARNING) << "locale_path_within_apk.empty() for locale " - << app_locale; return -1; } return base::android::OpenApkAsset(locale_path_within_apk, out_region); @@ -95,16 +98,20 @@ void ResourceBundle::LoadCommonResources() { // static bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { - if (g_locale_paks_in_apk) { - return !GetPathForAndroidLocalePakWithinApk(locale, false).empty(); + bool log_error = false; + bool in_split = !g_locale_paks_in_apk; + if (!in_split) { + return !GetPathForAndroidLocalePakWithinApk(locale, in_split, log_error) + .empty(); } - if (!GetPathForAndroidLocalePakWithinApk(locale, true).empty()) + if (!GetPathForAndroidLocalePakWithinApk(locale, in_split, log_error).empty()) return true; - return !GetLocaleFilePath(locale).empty(); + const auto path = GetLocaleFilePath(locale); + return !path.empty() && base::PathExists(path); } -std::string ResourceBundle::LoadLocaleResources( - const std::string& pref_locale) { +std::string ResourceBundle::LoadLocaleResources(const std::string& pref_locale, + bool crash_on_failure) { DCHECK(!locale_resources_data_.get() && !secondary_locale_resources_data_.get()) << "locale.pak already loaded"; @@ -166,8 +173,11 @@ std::string ResourceBundle::LoadLocaleResources( } if (g_locale_pack_fd < 0) { // Otherwise, try to locate the extracted locale .pak file. - if (locale_file_path.empty()) - locale_file_path = GetLocaleFilePath(app_locale); + if (locale_file_path.empty()) { + auto path = GetLocaleFilePath(app_locale); + if (base::PathExists(path)) + locale_file_path = std::move(path); + } if (locale_file_path.empty()) { // It's possible that there is no locale.pak. @@ -260,11 +270,13 @@ int GetSecondaryLocalePackFd(base::MemoryMappedFile::Region* out_region) { } std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale, - bool in_bundle) { + bool in_bundle, + bool log_error) { JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaLocalRef<jstring> ret = Java_ResourceBundle_getLocalePakResourcePath( - env, base::android::ConvertUTF8ToJavaString(env, locale), in_bundle); + env, base::android::ConvertUTF8ToJavaString(env, locale), in_bundle, + log_error); if (ret.obj() == nullptr) { return std::string(); } diff --git a/chromium/ui/base/resource/resource_bundle_android.h b/chromium/ui/base/resource/resource_bundle_android.h index e02fc11568f..99096888fc9 100644 --- a/chromium/ui/base/resource/resource_bundle_android.h +++ b/chromium/ui/base/resource/resource_bundle_android.h @@ -8,55 +8,57 @@ #include <jni.h> #include <string> +#include "base/component_export.h" #include "base/files/memory_mapped_file.h" -#include "ui/base/ui_base_export.h" namespace ui { // Loads "resources.apk" from the .apk. Falls back to loading from disk, which // is necessary for tests. -UI_BASE_EXPORT void LoadMainAndroidPackFile( - const char* path_within_apk, - const base::FilePath& disk_file_path); +COMPONENT_EXPORT(UI_BASE) +void LoadMainAndroidPackFile(const char* path_within_apk, + const base::FilePath& disk_file_path); // Loads a PAK file from the APK and makes the contained resources accessible. -UI_BASE_EXPORT void LoadPackFileFromApk(const std::string& path); +COMPONENT_EXPORT(UI_BASE) void LoadPackFileFromApk(const std::string& path); // Returns the file descriptor and region for resources.pak. -UI_BASE_EXPORT int GetMainAndroidPackFd( - base::MemoryMappedFile::Region* out_region); +COMPONENT_EXPORT(UI_BASE) +int GetMainAndroidPackFd(base::MemoryMappedFile::Region* out_region); // Returns the file descriptor and region for chrome_100_percent.pak. -UI_BASE_EXPORT int GetCommonResourcesPackFd( - base::MemoryMappedFile::Region* out_region); +COMPONENT_EXPORT(UI_BASE) +int GetCommonResourcesPackFd(base::MemoryMappedFile::Region* out_region); // Returns the file descriptor and region for the locale .pak file. -UI_BASE_EXPORT int GetLocalePackFd( - base::MemoryMappedFile::Region* out_region); +COMPONENT_EXPORT(UI_BASE) +int GetLocalePackFd(base::MemoryMappedFile::Region* out_region); // Returns the file descriptor and region for the secondary locale .pak file. -UI_BASE_EXPORT int GetSecondaryLocalePackFd( - base::MemoryMappedFile::Region* out_region); +COMPONENT_EXPORT(UI_BASE) +int GetSecondaryLocalePackFd(base::MemoryMappedFile::Region* out_region); // Tell ResourceBundle to locate locale pak files via // GetPathForAndroidLocalePakWithinApk rather than looking for them on disk. -UI_BASE_EXPORT void SetLocalePaksStoredInApk(bool value); +COMPONENT_EXPORT(UI_BASE) void SetLocalePaksStoredInApk(bool value); // Tell ResourceBundle to load secondary locale .pak files. -UI_BASE_EXPORT void SetLoadSecondaryLocalePaks(bool value); +COMPONENT_EXPORT(UI_BASE) void SetLoadSecondaryLocalePaks(bool value); // Returns the path within the apk for the given locale's .pak file, or an // empty string if it doesn't exist. // Only locale paks for the active Android language can be retrieved. -// If |inSplit| is true, look into bundle split-specific location (e.g. +// If |in_split| is true, look into bundle split-specific location (e.g. // 'assets/locales#lang_<lang>/<locale>.pak', otherwise use the default // WebView-related location, i.e. 'assets/stored-locales/<locale>.pak'. -UI_BASE_EXPORT std::string GetPathForAndroidLocalePakWithinApk( - const std::string& locale, - bool in_split = false); +// If |log_error|, logs the path to logcat, but does not abort. +COMPONENT_EXPORT(UI_BASE) +std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale, + bool in_split, + bool log_error); // Called in test when there are no locale pak files available. -UI_BASE_EXPORT void SetNoAvailableLocalePaksForTest(); +COMPONENT_EXPORT(UI_BASE) void SetNoAvailableLocalePaksForTest(); // Get the density of the primary display. Use this instead of using Display // to avoid initializing Display in child processes. diff --git a/chromium/ui/base/resource/resource_bundle_ios.mm b/chromium/ui/base/resource/resource_bundle_ios.mm index 111786882c6..f623bdf562d 100644 --- a/chromium/ui/base/resource/resource_bundle_ios.mm +++ b/chromium/ui/base/resource/resource_bundle_ios.mm @@ -13,6 +13,7 @@ #include "base/mac/foundation_util.h" #include "base/mac/scoped_nsobject.h" #include "base/memory/ref_counted_memory.h" +#include "base/notreached.h" #include "base/strings/sys_string_conversions.h" #include "base/synchronization/lock.h" #include "ui/base/resource/resource_handle.h" @@ -80,14 +81,8 @@ base::FilePath ResourceBundle::GetLocaleFilePath( locale_file_path, app_locale); } - // Don't try to load empty values or values that are not absolute paths. - if (locale_file_path.empty() || !locale_file_path.IsAbsolute()) - return base::FilePath(); - - if (!base::PathExists(locale_file_path)) - return base::FilePath(); - - return locale_file_path; + // Don't try to load from paths that are not absolute. + return locale_file_path.IsAbsolute() ? locale_file_path : base::FilePath(); } gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { diff --git a/chromium/ui/base/resource/resource_bundle_mac.mm b/chromium/ui/base/resource/resource_bundle_mac.mm index 6bd9d7aff19..87921ce6c6b 100644 --- a/chromium/ui/base/resource/resource_bundle_mac.mm +++ b/chromium/ui/base/resource/resource_bundle_mac.mm @@ -9,9 +9,11 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/logging.h" #include "base/mac/bundle_locations.h" #include "base/mac/scoped_nsobject.h" #include "base/memory/ref_counted_memory.h" +#include "base/notreached.h" #include "base/strings/sys_string_conversions.h" #include "base/synchronization/lock.h" #include "ui/base/resource/resource_handle.h" @@ -80,14 +82,8 @@ base::FilePath ResourceBundle::GetLocaleFilePath( locale_file_path, app_locale); } - // Don't try to load empty values or values that are not absolute paths. - if (locale_file_path.empty() || !locale_file_path.IsAbsolute()) - return base::FilePath(); - - if (!base::PathExists(locale_file_path)) - return base::FilePath(); - - return locale_file_path; + // Don't try to load from paths that are not absolute. + return locale_file_path.IsAbsolute() ? locale_file_path : base::FilePath(); } gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { diff --git a/chromium/ui/base/resource/resource_bundle_unittest.cc b/chromium/ui/base/resource/resource_bundle_unittest.cc index 904695c9291..bfa3dab5e80 100644 --- a/chromium/ui/base/resource/resource_bundle_unittest.cc +++ b/chromium/ui/base/resource/resource_bundle_unittest.cc @@ -163,16 +163,16 @@ TEST_F(ResourceBundleTest, DelegateGetPathForLocalePack) { .RetiresOnSaturation(); EXPECT_FALSE(ResourceBundle::LocaleDataPakExists(locale)); - EXPECT_EQ("", - ResourceBundle::GetSharedInstance().LoadLocaleResources(locale)); + EXPECT_EQ("", ResourceBundle::GetSharedInstance().LoadLocaleResources( + locale, /*crash_on_failure=*/false)); // Allow the load to proceed. EXPECT_CALL(delegate, GetPathForLocalePack(_, _)) .WillRepeatedly(ReturnArg<0>()); EXPECT_TRUE(ResourceBundle::LocaleDataPakExists(locale)); - EXPECT_EQ(locale, - ResourceBundle::GetSharedInstance().LoadLocaleResources(locale)); + EXPECT_EQ(locale, ResourceBundle::GetSharedInstance().LoadLocaleResources( + locale, /*crash_on_failure=*/false)); ResourceBundle::CleanupSharedInstance(); ResourceBundle::SwapSharedInstanceForTesting(orig_instance); diff --git a/chromium/ui/base/resource/resource_bundle_win.h b/chromium/ui/base/resource/resource_bundle_win.h index 92590eaff97..167f40c1ce3 100644 --- a/chromium/ui/base/resource/resource_bundle_win.h +++ b/chromium/ui/base/resource/resource_bundle_win.h @@ -9,16 +9,16 @@ #include <windows.h> -#include "ui/base/ui_base_export.h" +#include "base/component_export.h" namespace ui { // NOTE: This needs to be called before initializing ResourceBundle if your // resources are not stored in the executable. -UI_BASE_EXPORT void SetResourcesDataDLL(HINSTANCE handle); +COMPONENT_EXPORT(UI_BASE) void SetResourcesDataDLL(HINSTANCE handle); // Loads and returns an icon from the app module. -UI_BASE_EXPORT HICON LoadThemeIconFromResourcesDataDLL(int icon_id); +COMPONENT_EXPORT(UI_BASE) HICON LoadThemeIconFromResourcesDataDLL(int icon_id); } // namespace ui |