| 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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 output->append(" "); | 590 output->append(" "); |
| 597 output->append(is_public ? kPublic : kPrivate); | 591 output->append(is_public ? kPublic : kPrivate); |
| 598 output->append(" "); | 592 output->append(" "); |
| 599 output->append(kKeyInfoEndMarker); | 593 output->append(kKeyInfoEndMarker); |
| 600 output->append("\n"); | 594 output->append("\n"); |
| 601 | 595 |
| 602 return true; | 596 return true; |
| 603 } | 597 } |
| 604 | 598 |
| 605 // static | 599 // static |
| 606 void Extension::DecodeIcon(const Extension* extension, | |
| 607 int preferred_icon_size, | |
| 608 ExtensionIconSet::MatchType match_type, | |
| 609 scoped_ptr<SkBitmap>* result) { | |
| 610 std::string path = extension->icons().Get(preferred_icon_size, match_type); | |
| 611 int size = extension->icons().GetIconSizeFromPath(path); | |
| 612 ExtensionResource icon_resource = extension->GetResource(path); | |
| 613 DecodeIconFromPath(icon_resource.GetFilePath(), size, result); | |
| 614 } | |
| 615 | |
| 616 // static | |
| 617 void Extension::DecodeIcon(const Extension* extension, | |
| 618 int icon_size, | |
| 619 scoped_ptr<SkBitmap>* result) { | |
| 620 DecodeIcon(extension, icon_size, ExtensionIconSet::MATCH_EXACTLY, result); | |
| 621 } | |
| 622 | |
| 623 // static | |
| 624 void Extension::DecodeIconFromPath(const FilePath& icon_path, | |
| 625 int icon_size, | |
| 626 scoped_ptr<SkBitmap>* result) { | |
| 627 if (icon_path.empty()) | |
| 628 return; | |
| 629 | |
| 630 std::string file_contents; | |
| 631 if (!file_util::ReadFileToString(icon_path, &file_contents)) { | |
| 632 DLOG(ERROR) << "Could not read icon file: " << icon_path.LossyDisplayName(); | |
| 633 return; | |
| 634 } | |
| 635 | |
| 636 // Decode the image using WebKit's image decoder. | |
| 637 const unsigned char* data = | |
| 638 reinterpret_cast<const unsigned char*>(file_contents.data()); | |
| 639 webkit_glue::ImageDecoder decoder; | |
| 640 scoped_ptr<SkBitmap> decoded(new SkBitmap()); | |
| 641 *decoded = decoder.Decode(data, file_contents.length()); | |
| 642 if (decoded->empty()) { | |
| 643 DLOG(ERROR) << "Could not decode icon file: " | |
| 644 << icon_path.LossyDisplayName(); | |
| 645 return; | |
| 646 } | |
| 647 | |
| 648 if (decoded->width() != icon_size || decoded->height() != icon_size) { | |
| 649 DLOG(ERROR) << "Icon file has unexpected size: " | |
| 650 << base::IntToString(decoded->width()) << "x" | |
| 651 << base::IntToString(decoded->height()); | |
| 652 return; | |
| 653 } | |
| 654 | |
| 655 result->swap(decoded); | |
| 656 } | |
| 657 | |
| 658 // static | |
| 659 const gfx::ImageSkia& Extension::GetDefaultIcon(bool is_app) { | |
| 660 int id = is_app ? IDR_APP_DEFAULT_ICON : IDR_EXTENSION_DEFAULT_ICON; | |
| 661 return *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); | |
| 662 } | |
| 663 | |
| 664 // static | |
| 665 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { | 600 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { |
| 666 return GURL(std::string(extensions::kExtensionScheme) + | 601 return GURL(std::string(extensions::kExtensionScheme) + |
| 667 content::kStandardSchemeSeparator + extension_id + "/"); | 602 content::kStandardSchemeSeparator + extension_id + "/"); |
| 668 } | 603 } |
| 669 | 604 |
| 670 // static | 605 // static |
| 671 void Extension::SetScriptingWhitelist( | 606 void Extension::SetScriptingWhitelist( |
| 672 const Extension::ScriptingWhitelist& whitelist) { | 607 const Extension::ScriptingWhitelist& whitelist) { |
| 673 ScriptingWhitelist* current_whitelist = | 608 ScriptingWhitelist* current_whitelist = |
| 674 ExtensionConfig::GetInstance()->whitelist(); | 609 ExtensionConfig::GetInstance()->whitelist(); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 // no sense for component extensions. | 833 // no sense for component extensions. |
| 899 return location() != Extension::COMPONENT; | 834 return location() != Extension::COMPONENT; |
| 900 } | 835 } |
| 901 | 836 |
| 902 std::set<FilePath> Extension::GetBrowserImages() const { | 837 std::set<FilePath> Extension::GetBrowserImages() const { |
| 903 std::set<FilePath> image_paths; | 838 std::set<FilePath> image_paths; |
| 904 // TODO(viettrungluu): These |FilePath::FromWStringHack(UTF8ToWide())| | 839 // TODO(viettrungluu): These |FilePath::FromWStringHack(UTF8ToWide())| |
| 905 // indicate that we're doing something wrong. | 840 // indicate that we're doing something wrong. |
| 906 | 841 |
| 907 // Extension icons. | 842 // Extension icons. |
| 908 for (ExtensionIconSet::IconMap::const_iterator iter = icons().map().begin(); | 843 for (ExtensionIconSet::IconMap::const_iterator iter = |
| 909 iter != icons().map().end(); ++iter) { | 844 IconsInfo::GetIcons(this).map().begin(); |
| 845 iter != IconsInfo::GetIcons(this).map().end(); ++iter) { |
| 910 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); | 846 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); |
| 911 } | 847 } |
| 912 | 848 |
| 913 // Theme images. | 849 // Theme images. |
| 914 DictionaryValue* theme_images = GetThemeImages(); | 850 DictionaryValue* theme_images = GetThemeImages(); |
| 915 if (theme_images) { | 851 if (theme_images) { |
| 916 for (DictionaryValue::key_iterator it = theme_images->begin_keys(); | 852 for (DictionaryValue::key_iterator it = theme_images->begin_keys(); |
| 917 it != theme_images->end_keys(); ++it) { | 853 it != theme_images->end_keys(); ++it) { |
| 918 std::string val; | 854 std::string val; |
| 919 if (theme_images->GetStringWithoutPathExpansion(*it, &val)) | 855 if (theme_images->GetStringWithoutPathExpansion(*it, &val)) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 936 browser_action->default_icon.map().begin(); | 872 browser_action->default_icon.map().begin(); |
| 937 iter != browser_action->default_icon.map().end(); | 873 iter != browser_action->default_icon.map().end(); |
| 938 ++iter) { | 874 ++iter) { |
| 939 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); | 875 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); |
| 940 } | 876 } |
| 941 } | 877 } |
| 942 | 878 |
| 943 return image_paths; | 879 return image_paths; |
| 944 } | 880 } |
| 945 | 881 |
| 946 ExtensionResource Extension::GetIconResource( | |
| 947 int size, ExtensionIconSet::MatchType match_type) const { | |
| 948 std::string path = icons().Get(size, match_type); | |
| 949 return path.empty() ? ExtensionResource() : GetResource(path); | |
| 950 } | |
| 951 | |
| 952 GURL Extension::GetIconURL(int size, | |
| 953 ExtensionIconSet::MatchType match_type) const { | |
| 954 std::string path = icons().Get(size, match_type); | |
| 955 return path.empty() ? GURL() : GetResourceURL(path); | |
| 956 } | |
| 957 | |
| 958 GURL Extension::GetFullLaunchURL() const { | 882 GURL Extension::GetFullLaunchURL() const { |
| 959 return launch_local_path().empty() ? GURL(launch_web_url()) : | 883 return launch_local_path().empty() ? GURL(launch_web_url()) : |
| 960 url().Resolve(launch_local_path()); | 884 url().Resolve(launch_local_path()); |
| 961 } | 885 } |
| 962 | 886 |
| 963 void Extension::SetCachedImage(const ExtensionResource& source, | 887 void Extension::SetCachedImage(const ExtensionResource& source, |
| 964 const SkBitmap& image, | 888 const SkBitmap& image, |
| 965 const gfx::Size& original_size) const { | 889 const gfx::Size& original_size) const { |
| 966 DCHECK(source.extension_root() == path()); // The resource must come from | 890 DCHECK(source.extension_root() == path()); // The resource must come from |
| 967 // this extension. | 891 // this extension. |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1929 extent_.ClearPatterns(); | 1853 extent_.ClearPatterns(); |
| 1930 } | 1854 } |
| 1931 | 1855 |
| 1932 return true; | 1856 return true; |
| 1933 } | 1857 } |
| 1934 | 1858 |
| 1935 bool Extension::LoadSharedFeatures( | 1859 bool Extension::LoadSharedFeatures( |
| 1936 const APIPermissionSet& api_permissions, | 1860 const APIPermissionSet& api_permissions, |
| 1937 string16* error) { | 1861 string16* error) { |
| 1938 if (!LoadDescription(error) || | 1862 if (!LoadDescription(error) || |
| 1939 !LoadIcons(error) || | |
| 1940 !LoadCommands(error) || | 1863 !LoadCommands(error) || |
| 1941 !LoadPlugins(error) || | 1864 !LoadPlugins(error) || |
| 1942 !LoadNaClModules(error) || | 1865 !LoadNaClModules(error) || |
| 1943 !LoadWebAccessibleResources(error) || | 1866 !LoadWebAccessibleResources(error) || |
| 1944 !LoadSandboxedPages(error) || | 1867 !LoadSandboxedPages(error) || |
| 1945 !LoadRequirements(error) || | 1868 !LoadRequirements(error) || |
| 1946 !LoadDefaultLocale(error) || | 1869 !LoadDefaultLocale(error) || |
| 1947 !LoadOfflineEnabled(error) || | 1870 !LoadOfflineEnabled(error) || |
| 1948 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). | 1871 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). |
| 1949 !LoadBackgroundScripts(error) || | 1872 !LoadBackgroundScripts(error) || |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1984 switches::kAllowLegacyExtensionManifests)) { | 1907 switches::kAllowLegacyExtensionManifests)) { |
| 1985 *error = ErrorUtils::FormatErrorMessageUTF16( | 1908 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 1986 errors::kInvalidManifestVersionOld, | 1909 errors::kInvalidManifestVersionOld, |
| 1987 base::IntToString(kModernManifestVersion)); | 1910 base::IntToString(kModernManifestVersion)); |
| 1988 return false; | 1911 return false; |
| 1989 } | 1912 } |
| 1990 | 1913 |
| 1991 return true; | 1914 return true; |
| 1992 } | 1915 } |
| 1993 | 1916 |
| 1994 bool Extension::LoadIcons(string16* error) { | |
| 1995 if (!manifest_->HasKey(keys::kIcons)) | |
| 1996 return true; | |
| 1997 DictionaryValue* icons_value = NULL; | |
| 1998 if (!manifest_->GetDictionary(keys::kIcons, &icons_value)) { | |
| 1999 *error = ASCIIToUTF16(errors::kInvalidIcons); | |
| 2000 return false; | |
| 2001 } | |
| 2002 | |
| 2003 return manifest_handler_helpers::LoadIconsFromDictionary( | |
| 2004 icons_value, | |
| 2005 extension_misc::kExtensionIconSizes, | |
| 2006 extension_misc::kNumExtensionIconSizes, | |
| 2007 &icons_, | |
| 2008 error); | |
| 2009 } | |
| 2010 | |
| 2011 bool Extension::LoadCommands(string16* error) { | 1917 bool Extension::LoadCommands(string16* error) { |
| 2012 if (manifest_->HasKey(keys::kCommands)) { | 1918 if (manifest_->HasKey(keys::kCommands)) { |
| 2013 DictionaryValue* commands = NULL; | 1919 DictionaryValue* commands = NULL; |
| 2014 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { | 1920 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { |
| 2015 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); | 1921 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); |
| 2016 return false; | 1922 return false; |
| 2017 } | 1923 } |
| 2018 | 1924 |
| 2019 if (commands->size() > kMaxCommandsPerExtension) { | 1925 if (commands->size() > kMaxCommandsPerExtension) { |
| 2020 *error = ErrorUtils::FormatErrorMessageUTF16( | 1926 *error = ErrorUtils::FormatErrorMessageUTF16( |
| (...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3250 | 3156 |
| 3251 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3157 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 3252 const Extension* extension, | 3158 const Extension* extension, |
| 3253 const PermissionSet* permissions, | 3159 const PermissionSet* permissions, |
| 3254 Reason reason) | 3160 Reason reason) |
| 3255 : reason(reason), | 3161 : reason(reason), |
| 3256 extension(extension), | 3162 extension(extension), |
| 3257 permissions(permissions) {} | 3163 permissions(permissions) {} |
| 3258 | 3164 |
| 3259 } // namespace extensions | 3165 } // namespace extensions |
| OLD | NEW |