| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/extensions/extension.h" | 5 #include "chrome/common/extensions/extension.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" | |
| 14 #include "base/i18n/rtl.h" | 13 #include "base/i18n/rtl.h" |
| 15 #include "base/logging.h" | 14 #include "base/logging.h" |
| 16 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
| 17 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 18 #include "base/string16.h" | 17 #include "base/string16.h" |
| 19 #include "base/string_number_conversions.h" | 18 #include "base/string_number_conversions.h" |
| 20 #include "base/string_piece.h" | 19 #include "base/string_piece.h" |
| 21 #include "base/string_util.h" | 20 #include "base/string_util.h" |
| 22 #include "base/stringprintf.h" | 21 #include "base/stringprintf.h" |
| 23 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
| 24 #include "base/values.h" | 23 #include "base/values.h" |
| 25 #include "base/version.h" | 24 #include "base/version.h" |
| 26 #include "chrome/common/chrome_constants.h" | 25 #include "chrome/common/chrome_constants.h" |
| 27 #include "chrome/common/chrome_switches.h" | 26 #include "chrome/common/chrome_switches.h" |
| 28 #include "chrome/common/chrome_version_info.h" | 27 #include "chrome/common/chrome_version_info.h" |
| 29 // TODO(rdevlin.cronin): Remove this once PageAction, BrowserAction, and | 28 // TODO(rdevlin.cronin): Remove this once PageAction, BrowserAction, and |
| 30 // SystemIndicator have been moved out of Extension. | 29 // SystemIndicator have been moved out of Extension. |
| 31 #include "chrome/common/extensions/api/extension_action/action_info.h" | 30 #include "chrome/common/extensions/api/extension_action/action_info.h" |
| 31 #include "chrome/common/extensions/api/icons/icons_handler.h" |
| 32 #include "chrome/common/extensions/csp_validator.h" | 32 #include "chrome/common/extensions/csp_validator.h" |
| 33 #include "chrome/common/extensions/extension_manifest_constants.h" | 33 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 34 #include "chrome/common/extensions/extension_resource.h" | |
| 35 #include "chrome/common/extensions/feature_switch.h" | 34 #include "chrome/common/extensions/feature_switch.h" |
| 36 #include "chrome/common/extensions/features/base_feature_provider.h" | 35 #include "chrome/common/extensions/features/base_feature_provider.h" |
| 37 #include "chrome/common/extensions/features/feature.h" | 36 #include "chrome/common/extensions/features/feature.h" |
| 38 #include "chrome/common/extensions/manifest.h" | 37 #include "chrome/common/extensions/manifest.h" |
| 39 #include "chrome/common/extensions/manifest_handler.h" | 38 #include "chrome/common/extensions/manifest_handler.h" |
| 40 #include "chrome/common/extensions/manifest_handler_helpers.h" | 39 #include "chrome/common/extensions/manifest_handler_helpers.h" |
| 41 #include "chrome/common/extensions/manifest_url_handler.h" | 40 #include "chrome/common/extensions/manifest_url_handler.h" |
| 42 #include "chrome/common/extensions/permissions/permission_set.h" | 41 #include "chrome/common/extensions/permissions/permission_set.h" |
| 43 #include "chrome/common/extensions/permissions/permissions_info.h" | 42 #include "chrome/common/extensions/permissions/permissions_info.h" |
| 44 #include "chrome/common/extensions/user_script.h" | 43 #include "chrome/common/extensions/user_script.h" |
| 45 #include "chrome/common/url_constants.h" | 44 #include "chrome/common/url_constants.h" |
| 46 #include "crypto/sha2.h" | 45 #include "crypto/sha2.h" |
| 47 #include "extensions/common/constants.h" | 46 #include "extensions/common/constants.h" |
| 48 #include "extensions/common/error_utils.h" | 47 #include "extensions/common/error_utils.h" |
| 49 #include "extensions/common/url_pattern_set.h" | 48 #include "extensions/common/url_pattern_set.h" |
| 50 #include "googleurl/src/url_util.h" | 49 #include "googleurl/src/url_util.h" |
| 51 #include "grit/chromium_strings.h" | 50 #include "grit/chromium_strings.h" |
| 52 #include "grit/theme_resources.h" | 51 #include "grit/theme_resources.h" |
| 53 #include "third_party/skia/include/core/SkBitmap.h" | 52 #include "third_party/skia/include/core/SkBitmap.h" |
| 54 #include "ui/base/l10n/l10n_util.h" | 53 #include "ui/base/l10n/l10n_util.h" |
| 55 #include "ui/base/resource/resource_bundle.h" | |
| 56 #include "webkit/glue/image_decoder.h" | |
| 57 | 54 |
| 58 #if defined(OS_WIN) | 55 #if defined(OS_WIN) |
| 59 #include "base/win/metro.h" | 56 #include "base/win/metro.h" |
| 60 #include "grit/generated_resources.h" | 57 #include "grit/generated_resources.h" |
| 61 #endif | 58 #endif |
| 62 | 59 |
| 63 namespace keys = extension_manifest_keys; | 60 namespace keys = extension_manifest_keys; |
| 64 namespace values = extension_manifest_values; | 61 namespace values = extension_manifest_values; |
| 65 namespace errors = extension_manifest_errors; | 62 namespace errors = extension_manifest_errors; |
| 66 namespace info_keys = extension_info_keys; | 63 namespace info_keys = extension_info_keys; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 #if defined(OS_WIN) | 285 #if defined(OS_WIN) |
| 289 const char Extension::kExtensionRegistryPath[] = | 286 const char Extension::kExtensionRegistryPath[] = |
| 290 "Software\\Google\\Chrome\\Extensions"; | 287 "Software\\Google\\Chrome\\Extensions"; |
| 291 #endif | 288 #endif |
| 292 | 289 |
| 293 // first 16 bytes of SHA256 hashed public key. | 290 // first 16 bytes of SHA256 hashed public key. |
| 294 const size_t Extension::kIdSize = 16; | 291 const size_t Extension::kIdSize = 16; |
| 295 | 292 |
| 296 const char Extension::kMimeType[] = "application/x-chrome-extension"; | 293 const char Extension::kMimeType[] = "application/x-chrome-extension"; |
| 297 | 294 |
| 298 const int Extension::kPageActionIconMaxSize = 19; | |
| 299 const int Extension::kBrowserActionIconMaxSize = 19; | |
| 300 | |
| 301 const int Extension::kValidWebExtentSchemes = | 295 const int Extension::kValidWebExtentSchemes = |
| 302 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; | 296 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; |
| 303 | 297 |
| 304 const int Extension::kValidHostPermissionSchemes = | 298 const int Extension::kValidHostPermissionSchemes = |
| 305 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; | 299 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; |
| 306 | 300 |
| 307 Extension::Requirements::Requirements() | 301 Extension::Requirements::Requirements() |
| 308 : webgl(false), | 302 : webgl(false), |
| 309 css3d(false), | 303 css3d(false), |
| 310 npapi(false) { | 304 npapi(false) { |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 output->append(" "); | 576 output->append(" "); |
| 583 output->append(is_public ? kPublic : kPrivate); | 577 output->append(is_public ? kPublic : kPrivate); |
| 584 output->append(" "); | 578 output->append(" "); |
| 585 output->append(kKeyInfoEndMarker); | 579 output->append(kKeyInfoEndMarker); |
| 586 output->append("\n"); | 580 output->append("\n"); |
| 587 | 581 |
| 588 return true; | 582 return true; |
| 589 } | 583 } |
| 590 | 584 |
| 591 // static | 585 // static |
| 592 void Extension::DecodeIcon(const Extension* extension, | |
| 593 int preferred_icon_size, | |
| 594 ExtensionIconSet::MatchType match_type, | |
| 595 scoped_ptr<SkBitmap>* result) { | |
| 596 std::string path = extension->icons().Get(preferred_icon_size, match_type); | |
| 597 int size = extension->icons().GetIconSizeFromPath(path); | |
| 598 ExtensionResource icon_resource = extension->GetResource(path); | |
| 599 DecodeIconFromPath(icon_resource.GetFilePath(), size, result); | |
| 600 } | |
| 601 | |
| 602 // static | |
| 603 void Extension::DecodeIcon(const Extension* extension, | |
| 604 int icon_size, | |
| 605 scoped_ptr<SkBitmap>* result) { | |
| 606 DecodeIcon(extension, icon_size, ExtensionIconSet::MATCH_EXACTLY, result); | |
| 607 } | |
| 608 | |
| 609 // static | |
| 610 void Extension::DecodeIconFromPath(const FilePath& icon_path, | |
| 611 int icon_size, | |
| 612 scoped_ptr<SkBitmap>* result) { | |
| 613 if (icon_path.empty()) | |
| 614 return; | |
| 615 | |
| 616 std::string file_contents; | |
| 617 if (!file_util::ReadFileToString(icon_path, &file_contents)) { | |
| 618 DLOG(ERROR) << "Could not read icon file: " << icon_path.LossyDisplayName(); | |
| 619 return; | |
| 620 } | |
| 621 | |
| 622 // Decode the image using WebKit's image decoder. | |
| 623 const unsigned char* data = | |
| 624 reinterpret_cast<const unsigned char*>(file_contents.data()); | |
| 625 webkit_glue::ImageDecoder decoder; | |
| 626 scoped_ptr<SkBitmap> decoded(new SkBitmap()); | |
| 627 *decoded = decoder.Decode(data, file_contents.length()); | |
| 628 if (decoded->empty()) { | |
| 629 DLOG(ERROR) << "Could not decode icon file: " | |
| 630 << icon_path.LossyDisplayName(); | |
| 631 return; | |
| 632 } | |
| 633 | |
| 634 if (decoded->width() != icon_size || decoded->height() != icon_size) { | |
| 635 DLOG(ERROR) << "Icon file has unexpected size: " | |
| 636 << base::IntToString(decoded->width()) << "x" | |
| 637 << base::IntToString(decoded->height()); | |
| 638 return; | |
| 639 } | |
| 640 | |
| 641 result->swap(decoded); | |
| 642 } | |
| 643 | |
| 644 // static | |
| 645 const gfx::ImageSkia& Extension::GetDefaultIcon(bool is_app) { | |
| 646 int id = is_app ? IDR_APP_DEFAULT_ICON : IDR_EXTENSION_DEFAULT_ICON; | |
| 647 return *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); | |
| 648 } | |
| 649 | |
| 650 // static | |
| 651 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { | 586 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { |
| 652 return GURL(std::string(extensions::kExtensionScheme) + | 587 return GURL(std::string(extensions::kExtensionScheme) + |
| 653 content::kStandardSchemeSeparator + extension_id + "/"); | 588 content::kStandardSchemeSeparator + extension_id + "/"); |
| 654 } | 589 } |
| 655 | 590 |
| 656 // static | 591 // static |
| 657 void Extension::SetScriptingWhitelist( | 592 void Extension::SetScriptingWhitelist( |
| 658 const Extension::ScriptingWhitelist& whitelist) { | 593 const Extension::ScriptingWhitelist& whitelist) { |
| 659 ScriptingWhitelist* current_whitelist = | 594 ScriptingWhitelist* current_whitelist = |
| 660 ExtensionConfig::GetInstance()->whitelist(); | 595 ExtensionConfig::GetInstance()->whitelist(); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 // no sense for component extensions. | 819 // no sense for component extensions. |
| 885 return location() != Extension::COMPONENT; | 820 return location() != Extension::COMPONENT; |
| 886 } | 821 } |
| 887 | 822 |
| 888 std::set<FilePath> Extension::GetBrowserImages() const { | 823 std::set<FilePath> Extension::GetBrowserImages() const { |
| 889 std::set<FilePath> image_paths; | 824 std::set<FilePath> image_paths; |
| 890 // TODO(viettrungluu): These |FilePath::FromWStringHack(UTF8ToWide())| | 825 // TODO(viettrungluu): These |FilePath::FromWStringHack(UTF8ToWide())| |
| 891 // indicate that we're doing something wrong. | 826 // indicate that we're doing something wrong. |
| 892 | 827 |
| 893 // Extension icons. | 828 // Extension icons. |
| 894 for (ExtensionIconSet::IconMap::const_iterator iter = icons().map().begin(); | 829 for (ExtensionIconSet::IconMap::const_iterator iter = |
| 895 iter != icons().map().end(); ++iter) { | 830 IconsInfo::GetIcons(this).map().begin(); |
| 831 iter != IconsInfo::GetIcons(this).map().end(); ++iter) { |
| 896 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); | 832 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); |
| 897 } | 833 } |
| 898 | 834 |
| 899 // Theme images. | 835 // Theme images. |
| 900 DictionaryValue* theme_images = GetThemeImages(); | 836 DictionaryValue* theme_images = GetThemeImages(); |
| 901 if (theme_images) { | 837 if (theme_images) { |
| 902 for (DictionaryValue::Iterator it(*theme_images); !it.IsAtEnd(); | 838 for (DictionaryValue::Iterator it(*theme_images); !it.IsAtEnd(); |
| 903 it.Advance()) { | 839 it.Advance()) { |
| 904 std::string val; | 840 std::string val; |
| 905 if (it.value().GetAsString(&val)) | 841 if (it.value().GetAsString(&val)) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 921 browser_action_info()->default_icon.map().begin(); | 857 browser_action_info()->default_icon.map().begin(); |
| 922 iter != browser_action_info()->default_icon.map().end(); | 858 iter != browser_action_info()->default_icon.map().end(); |
| 923 ++iter) { | 859 ++iter) { |
| 924 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); | 860 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); |
| 925 } | 861 } |
| 926 } | 862 } |
| 927 | 863 |
| 928 return image_paths; | 864 return image_paths; |
| 929 } | 865 } |
| 930 | 866 |
| 931 ExtensionResource Extension::GetIconResource( | |
| 932 int size, ExtensionIconSet::MatchType match_type) const { | |
| 933 std::string path = icons().Get(size, match_type); | |
| 934 return path.empty() ? ExtensionResource() : GetResource(path); | |
| 935 } | |
| 936 | |
| 937 GURL Extension::GetIconURL(int size, | |
| 938 ExtensionIconSet::MatchType match_type) const { | |
| 939 std::string path = icons().Get(size, match_type); | |
| 940 return path.empty() ? GURL() : GetResourceURL(path); | |
| 941 } | |
| 942 | |
| 943 GURL Extension::GetFullLaunchURL() const { | 867 GURL Extension::GetFullLaunchURL() const { |
| 944 return launch_local_path().empty() ? GURL(launch_web_url()) : | 868 return launch_local_path().empty() ? GURL(launch_web_url()) : |
| 945 url().Resolve(launch_local_path()); | 869 url().Resolve(launch_local_path()); |
| 946 } | 870 } |
| 947 | 871 |
| 948 void Extension::SetCachedImage(const ExtensionResource& source, | 872 void Extension::SetCachedImage(const ExtensionResource& source, |
| 949 const SkBitmap& image, | 873 const SkBitmap& image, |
| 950 const gfx::Size& original_size) const { | 874 const gfx::Size& original_size) const { |
| 951 DCHECK(source.extension_root() == path()); // The resource must come from | 875 DCHECK(source.extension_root() == path()); // The resource must come from |
| 952 // this extension. | 876 // this extension. |
| (...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1913 extent_.ClearPatterns(); | 1837 extent_.ClearPatterns(); |
| 1914 } | 1838 } |
| 1915 | 1839 |
| 1916 return true; | 1840 return true; |
| 1917 } | 1841 } |
| 1918 | 1842 |
| 1919 bool Extension::LoadSharedFeatures( | 1843 bool Extension::LoadSharedFeatures( |
| 1920 const APIPermissionSet& api_permissions, | 1844 const APIPermissionSet& api_permissions, |
| 1921 string16* error) { | 1845 string16* error) { |
| 1922 if (!LoadDescription(error) || | 1846 if (!LoadDescription(error) || |
| 1923 !LoadIcons(error) || | |
| 1924 !LoadPlugins(error) || | 1847 !LoadPlugins(error) || |
| 1925 !LoadNaClModules(error) || | 1848 !LoadNaClModules(error) || |
| 1926 !LoadSandboxedPages(error) || | 1849 !LoadSandboxedPages(error) || |
| 1927 !LoadRequirements(error) || | 1850 !LoadRequirements(error) || |
| 1928 !LoadDefaultLocale(error) || | 1851 !LoadDefaultLocale(error) || |
| 1929 !LoadOfflineEnabled(error) || | 1852 !LoadOfflineEnabled(error) || |
| 1930 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). | 1853 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). |
| 1931 !LoadBackgroundScripts(error) || | 1854 !LoadBackgroundScripts(error) || |
| 1932 !LoadBackgroundPage(api_permissions, error) || | 1855 !LoadBackgroundPage(api_permissions, error) || |
| 1933 !LoadBackgroundPersistent(api_permissions, error) || | 1856 !LoadBackgroundPersistent(api_permissions, error) || |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1966 switches::kAllowLegacyExtensionManifests)) { | 1889 switches::kAllowLegacyExtensionManifests)) { |
| 1967 *error = ErrorUtils::FormatErrorMessageUTF16( | 1890 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 1968 errors::kInvalidManifestVersionOld, | 1891 errors::kInvalidManifestVersionOld, |
| 1969 base::IntToString(kModernManifestVersion)); | 1892 base::IntToString(kModernManifestVersion)); |
| 1970 return false; | 1893 return false; |
| 1971 } | 1894 } |
| 1972 | 1895 |
| 1973 return true; | 1896 return true; |
| 1974 } | 1897 } |
| 1975 | 1898 |
| 1976 bool Extension::LoadIcons(string16* error) { | |
| 1977 if (!manifest_->HasKey(keys::kIcons)) | |
| 1978 return true; | |
| 1979 DictionaryValue* icons_value = NULL; | |
| 1980 if (!manifest_->GetDictionary(keys::kIcons, &icons_value)) { | |
| 1981 *error = ASCIIToUTF16(errors::kInvalidIcons); | |
| 1982 return false; | |
| 1983 } | |
| 1984 | |
| 1985 return manifest_handler_helpers::LoadIconsFromDictionary( | |
| 1986 icons_value, | |
| 1987 extension_misc::kExtensionIconSizes, | |
| 1988 extension_misc::kNumExtensionIconSizes, | |
| 1989 &icons_, | |
| 1990 error); | |
| 1991 } | |
| 1992 | |
| 1993 bool Extension::LoadPlugins(string16* error) { | 1899 bool Extension::LoadPlugins(string16* error) { |
| 1994 if (!manifest_->HasKey(keys::kPlugins)) | 1900 if (!manifest_->HasKey(keys::kPlugins)) |
| 1995 return true; | 1901 return true; |
| 1996 | 1902 |
| 1997 ListValue* list_value = NULL; | 1903 ListValue* list_value = NULL; |
| 1998 if (!manifest_->GetList(keys::kPlugins, &list_value)) { | 1904 if (!manifest_->GetList(keys::kPlugins, &list_value)) { |
| 1999 *error = ASCIIToUTF16(errors::kInvalidPlugins); | 1905 *error = ASCIIToUTF16(errors::kInvalidPlugins); |
| 2000 return false; | 1906 return false; |
| 2001 } | 1907 } |
| 2002 | 1908 |
| (...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3158 | 3064 |
| 3159 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3065 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 3160 const Extension* extension, | 3066 const Extension* extension, |
| 3161 const PermissionSet* permissions, | 3067 const PermissionSet* permissions, |
| 3162 Reason reason) | 3068 Reason reason) |
| 3163 : reason(reason), | 3069 : reason(reason), |
| 3164 extension(extension), | 3070 extension(extension), |
| 3165 permissions(permissions) {} | 3071 permissions(permissions) {} |
| 3166 | 3072 |
| 3167 } // namespace extensions | 3073 } // namespace extensions |
| OLD | NEW |