| OLD | NEW |
| 1 // Copyright (c) 2012 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/permissions/permission_set.h" | 40 #include "chrome/common/extensions/permissions/permission_set.h" |
| 42 #include "chrome/common/extensions/permissions/permissions_info.h" | 41 #include "chrome/common/extensions/permissions/permissions_info.h" |
| 43 #include "chrome/common/extensions/user_script.h" | 42 #include "chrome/common/extensions/user_script.h" |
| 44 #include "chrome/common/url_constants.h" | 43 #include "chrome/common/url_constants.h" |
| 45 #include "crypto/sha2.h" | 44 #include "crypto/sha2.h" |
| 46 #include "extensions/common/constants.h" | 45 #include "extensions/common/constants.h" |
| 47 #include "extensions/common/error_utils.h" | 46 #include "extensions/common/error_utils.h" |
| 48 #include "extensions/common/url_pattern_set.h" | 47 #include "extensions/common/url_pattern_set.h" |
| 49 #include "googleurl/src/url_util.h" | 48 #include "googleurl/src/url_util.h" |
| 50 #include "grit/chromium_strings.h" | 49 #include "grit/chromium_strings.h" |
| 51 #include "grit/theme_resources.h" | 50 #include "grit/theme_resources.h" |
| 52 #include "third_party/skia/include/core/SkBitmap.h" | 51 #include "third_party/skia/include/core/SkBitmap.h" |
| 53 #include "ui/base/l10n/l10n_util.h" | 52 #include "ui/base/l10n/l10n_util.h" |
| 54 #include "ui/base/resource/resource_bundle.h" | |
| 55 #include "webkit/glue/image_decoder.h" | |
| 56 #include "webkit/glue/web_intent_service_data.h" | 53 #include "webkit/glue/web_intent_service_data.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; |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 #if defined(OS_WIN) | 287 #if defined(OS_WIN) |
| 291 const char Extension::kExtensionRegistryPath[] = | 288 const char Extension::kExtensionRegistryPath[] = |
| 292 "Software\\Google\\Chrome\\Extensions"; | 289 "Software\\Google\\Chrome\\Extensions"; |
| 293 #endif | 290 #endif |
| 294 | 291 |
| 295 // first 16 bytes of SHA256 hashed public key. | 292 // first 16 bytes of SHA256 hashed public key. |
| 296 const size_t Extension::kIdSize = 16; | 293 const size_t Extension::kIdSize = 16; |
| 297 | 294 |
| 298 const char Extension::kMimeType[] = "application/x-chrome-extension"; | 295 const char Extension::kMimeType[] = "application/x-chrome-extension"; |
| 299 | 296 |
| 300 const int Extension::kPageActionIconMaxSize = 19; | |
| 301 const int Extension::kBrowserActionIconMaxSize = 19; | |
| 302 | |
| 303 const int Extension::kValidWebExtentSchemes = | 297 const int Extension::kValidWebExtentSchemes = |
| 304 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; | 298 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; |
| 305 | 299 |
| 306 const int Extension::kValidHostPermissionSchemes = | 300 const int Extension::kValidHostPermissionSchemes = |
| 307 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; | 301 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; |
| 308 | 302 |
| 309 Extension::Requirements::Requirements() | 303 Extension::Requirements::Requirements() |
| 310 : webgl(false), | 304 : webgl(false), |
| 311 css3d(false), | 305 css3d(false), |
| 312 npapi(false) { | 306 npapi(false) { |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 output->append(" "); | 598 output->append(" "); |
| 605 output->append(is_public ? kPublic : kPrivate); | 599 output->append(is_public ? kPublic : kPrivate); |
| 606 output->append(" "); | 600 output->append(" "); |
| 607 output->append(kKeyInfoEndMarker); | 601 output->append(kKeyInfoEndMarker); |
| 608 output->append("\n"); | 602 output->append("\n"); |
| 609 | 603 |
| 610 return true; | 604 return true; |
| 611 } | 605 } |
| 612 | 606 |
| 613 // static | 607 // static |
| 614 void Extension::DecodeIcon(const Extension* extension, | |
| 615 int preferred_icon_size, | |
| 616 ExtensionIconSet::MatchType match_type, | |
| 617 scoped_ptr<SkBitmap>* result) { | |
| 618 std::string path = extension->icons().Get(preferred_icon_size, match_type); | |
| 619 int size = extension->icons().GetIconSizeFromPath(path); | |
| 620 ExtensionResource icon_resource = extension->GetResource(path); | |
| 621 DecodeIconFromPath(icon_resource.GetFilePath(), size, result); | |
| 622 } | |
| 623 | |
| 624 // static | |
| 625 void Extension::DecodeIcon(const Extension* extension, | |
| 626 int icon_size, | |
| 627 scoped_ptr<SkBitmap>* result) { | |
| 628 DecodeIcon(extension, icon_size, ExtensionIconSet::MATCH_EXACTLY, result); | |
| 629 } | |
| 630 | |
| 631 // static | |
| 632 void Extension::DecodeIconFromPath(const FilePath& icon_path, | |
| 633 int icon_size, | |
| 634 scoped_ptr<SkBitmap>* result) { | |
| 635 if (icon_path.empty()) | |
| 636 return; | |
| 637 | |
| 638 std::string file_contents; | |
| 639 if (!file_util::ReadFileToString(icon_path, &file_contents)) { | |
| 640 DLOG(ERROR) << "Could not read icon file: " << icon_path.LossyDisplayName(); | |
| 641 return; | |
| 642 } | |
| 643 | |
| 644 // Decode the image using WebKit's image decoder. | |
| 645 const unsigned char* data = | |
| 646 reinterpret_cast<const unsigned char*>(file_contents.data()); | |
| 647 webkit_glue::ImageDecoder decoder; | |
| 648 scoped_ptr<SkBitmap> decoded(new SkBitmap()); | |
| 649 *decoded = decoder.Decode(data, file_contents.length()); | |
| 650 if (decoded->empty()) { | |
| 651 DLOG(ERROR) << "Could not decode icon file: " | |
| 652 << icon_path.LossyDisplayName(); | |
| 653 return; | |
| 654 } | |
| 655 | |
| 656 if (decoded->width() != icon_size || decoded->height() != icon_size) { | |
| 657 DLOG(ERROR) << "Icon file has unexpected size: " | |
| 658 << base::IntToString(decoded->width()) << "x" | |
| 659 << base::IntToString(decoded->height()); | |
| 660 return; | |
| 661 } | |
| 662 | |
| 663 result->swap(decoded); | |
| 664 } | |
| 665 | |
| 666 // static | |
| 667 const gfx::ImageSkia& Extension::GetDefaultIcon(bool is_app) { | |
| 668 int id = is_app ? IDR_APP_DEFAULT_ICON : IDR_EXTENSION_DEFAULT_ICON; | |
| 669 return *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); | |
| 670 } | |
| 671 | |
| 672 // static | |
| 673 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { | 608 GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { |
| 674 return GURL(std::string(extensions::kExtensionScheme) + | 609 return GURL(std::string(extensions::kExtensionScheme) + |
| 675 content::kStandardSchemeSeparator + extension_id + "/"); | 610 content::kStandardSchemeSeparator + extension_id + "/"); |
| 676 } | 611 } |
| 677 | 612 |
| 678 // static | 613 // static |
| 679 void Extension::SetScriptingWhitelist( | 614 void Extension::SetScriptingWhitelist( |
| 680 const Extension::ScriptingWhitelist& whitelist) { | 615 const Extension::ScriptingWhitelist& whitelist) { |
| 681 ScriptingWhitelist* current_whitelist = | 616 ScriptingWhitelist* current_whitelist = |
| 682 ExtensionConfig::GetInstance()->whitelist(); | 617 ExtensionConfig::GetInstance()->whitelist(); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 return UpdatesFromGallery() ? | 849 return UpdatesFromGallery() ? |
| 915 GURL(extension_urls::GetWebstoreItemDetailURLPrefix() + id()) : GURL(); | 850 GURL(extension_urls::GetWebstoreItemDetailURLPrefix() + id()) : GURL(); |
| 916 } | 851 } |
| 917 | 852 |
| 918 std::set<FilePath> Extension::GetBrowserImages() const { | 853 std::set<FilePath> Extension::GetBrowserImages() const { |
| 919 std::set<FilePath> image_paths; | 854 std::set<FilePath> image_paths; |
| 920 // TODO(viettrungluu): These |FilePath::FromWStringHack(UTF8ToWide())| | 855 // TODO(viettrungluu): These |FilePath::FromWStringHack(UTF8ToWide())| |
| 921 // indicate that we're doing something wrong. | 856 // indicate that we're doing something wrong. |
| 922 | 857 |
| 923 // Extension icons. | 858 // Extension icons. |
| 924 for (ExtensionIconSet::IconMap::const_iterator iter = icons().map().begin(); | 859 for (ExtensionIconSet::IconMap::const_iterator iter = |
| 925 iter != icons().map().end(); ++iter) { | 860 IconsInfo::GetIcons(this).map().begin(); |
| 861 iter != IconsInfo::GetIcons(this).map().end(); ++iter) { |
| 926 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); | 862 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); |
| 927 } | 863 } |
| 928 | 864 |
| 929 // Theme images. | 865 // Theme images. |
| 930 DictionaryValue* theme_images = GetThemeImages(); | 866 DictionaryValue* theme_images = GetThemeImages(); |
| 931 if (theme_images) { | 867 if (theme_images) { |
| 932 for (DictionaryValue::key_iterator it = theme_images->begin_keys(); | 868 for (DictionaryValue::key_iterator it = theme_images->begin_keys(); |
| 933 it != theme_images->end_keys(); ++it) { | 869 it != theme_images->end_keys(); ++it) { |
| 934 std::string val; | 870 std::string val; |
| 935 if (theme_images->GetStringWithoutPathExpansion(*it, &val)) | 871 if (theme_images->GetStringWithoutPathExpansion(*it, &val)) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 952 browser_action->default_icon.map().begin(); | 888 browser_action->default_icon.map().begin(); |
| 953 iter != browser_action->default_icon.map().end(); | 889 iter != browser_action->default_icon.map().end(); |
| 954 ++iter) { | 890 ++iter) { |
| 955 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); | 891 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); |
| 956 } | 892 } |
| 957 } | 893 } |
| 958 | 894 |
| 959 return image_paths; | 895 return image_paths; |
| 960 } | 896 } |
| 961 | 897 |
| 962 ExtensionResource Extension::GetIconResource( | |
| 963 int size, ExtensionIconSet::MatchType match_type) const { | |
| 964 std::string path = icons().Get(size, match_type); | |
| 965 return path.empty() ? ExtensionResource() : GetResource(path); | |
| 966 } | |
| 967 | |
| 968 GURL Extension::GetIconURL(int size, | |
| 969 ExtensionIconSet::MatchType match_type) const { | |
| 970 std::string path = icons().Get(size, match_type); | |
| 971 return path.empty() ? GURL() : GetResourceURL(path); | |
| 972 } | |
| 973 | |
| 974 GURL Extension::GetFullLaunchURL() const { | 898 GURL Extension::GetFullLaunchURL() const { |
| 975 return launch_local_path().empty() ? GURL(launch_web_url()) : | 899 return launch_local_path().empty() ? GURL(launch_web_url()) : |
| 976 url().Resolve(launch_local_path()); | 900 url().Resolve(launch_local_path()); |
| 977 } | 901 } |
| 978 | 902 |
| 979 void Extension::SetCachedImage(const ExtensionResource& source, | 903 void Extension::SetCachedImage(const ExtensionResource& source, |
| 980 const SkBitmap& image, | 904 const SkBitmap& image, |
| 981 const gfx::Size& original_size) const { | 905 const gfx::Size& original_size) const { |
| 982 DCHECK(source.extension_root() == path()); // The resource must come from | 906 DCHECK(source.extension_root() == path()); // The resource must come from |
| 983 // this extension. | 907 // this extension. |
| (...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1892 | 1816 |
| 1893 return true; | 1817 return true; |
| 1894 } | 1818 } |
| 1895 | 1819 |
| 1896 bool Extension::LoadSharedFeatures( | 1820 bool Extension::LoadSharedFeatures( |
| 1897 const APIPermissionSet& api_permissions, | 1821 const APIPermissionSet& api_permissions, |
| 1898 string16* error) { | 1822 string16* error) { |
| 1899 if (!LoadDescription(error) || | 1823 if (!LoadDescription(error) || |
| 1900 !LoadHomepageURL(error) || | 1824 !LoadHomepageURL(error) || |
| 1901 !LoadUpdateURL(error) || | 1825 !LoadUpdateURL(error) || |
| 1902 !LoadIcons(error) || | |
| 1903 !LoadCommands(error) || | 1826 !LoadCommands(error) || |
| 1904 !LoadPlugins(error) || | 1827 !LoadPlugins(error) || |
| 1905 !LoadNaClModules(error) || | 1828 !LoadNaClModules(error) || |
| 1906 !LoadWebAccessibleResources(error) || | 1829 !LoadWebAccessibleResources(error) || |
| 1907 !LoadSandboxedPages(error) || | 1830 !LoadSandboxedPages(error) || |
| 1908 !LoadRequirements(error) || | 1831 !LoadRequirements(error) || |
| 1909 !LoadDefaultLocale(error) || | 1832 !LoadDefaultLocale(error) || |
| 1910 !LoadOfflineEnabled(error) || | 1833 !LoadOfflineEnabled(error) || |
| 1911 !LoadOptionsPage(error) || | 1834 !LoadOptionsPage(error) || |
| 1912 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). | 1835 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1988 update_url_ = GURL(tmp_update_url); | 1911 update_url_ = GURL(tmp_update_url); |
| 1989 if (!update_url_.is_valid() || | 1912 if (!update_url_.is_valid() || |
| 1990 update_url_.has_ref()) { | 1913 update_url_.has_ref()) { |
| 1991 *error = ErrorUtils::FormatErrorMessageUTF16( | 1914 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 1992 errors::kInvalidUpdateURL, tmp_update_url); | 1915 errors::kInvalidUpdateURL, tmp_update_url); |
| 1993 return false; | 1916 return false; |
| 1994 } | 1917 } |
| 1995 return true; | 1918 return true; |
| 1996 } | 1919 } |
| 1997 | 1920 |
| 1998 bool Extension::LoadIcons(string16* error) { | |
| 1999 if (!manifest_->HasKey(keys::kIcons)) | |
| 2000 return true; | |
| 2001 DictionaryValue* icons_value = NULL; | |
| 2002 if (!manifest_->GetDictionary(keys::kIcons, &icons_value)) { | |
| 2003 *error = ASCIIToUTF16(errors::kInvalidIcons); | |
| 2004 return false; | |
| 2005 } | |
| 2006 | |
| 2007 return manifest_handler_helpers::LoadIconsFromDictionary( | |
| 2008 icons_value, | |
| 2009 extension_misc::kExtensionIconSizes, | |
| 2010 extension_misc::kNumExtensionIconSizes, | |
| 2011 &icons_, | |
| 2012 error); | |
| 2013 } | |
| 2014 | |
| 2015 bool Extension::LoadCommands(string16* error) { | 1921 bool Extension::LoadCommands(string16* error) { |
| 2016 if (manifest_->HasKey(keys::kCommands)) { | 1922 if (manifest_->HasKey(keys::kCommands)) { |
| 2017 DictionaryValue* commands = NULL; | 1923 DictionaryValue* commands = NULL; |
| 2018 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { | 1924 if (!manifest_->GetDictionary(keys::kCommands, &commands)) { |
| 2019 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); | 1925 *error = ASCIIToUTF16(errors::kInvalidCommandsKey); |
| 2020 return false; | 1926 return false; |
| 2021 } | 1927 } |
| 2022 | 1928 |
| 2023 if (commands->size() > kMaxCommandsPerExtension) { | 1929 if (commands->size() > kMaxCommandsPerExtension) { |
| 2024 *error = ErrorUtils::FormatErrorMessageUTF16( | 1930 *error = ErrorUtils::FormatErrorMessageUTF16( |
| (...skipping 1652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3677 | 3583 |
| 3678 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3584 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 3679 const Extension* extension, | 3585 const Extension* extension, |
| 3680 const PermissionSet* permissions, | 3586 const PermissionSet* permissions, |
| 3681 Reason reason) | 3587 Reason reason) |
| 3682 : reason(reason), | 3588 : reason(reason), |
| 3683 extension(extension), | 3589 extension(extension), |
| 3684 permissions(permissions) {} | 3590 permissions(permissions) {} |
| 3685 | 3591 |
| 3686 } // namespace extensions | 3592 } // namespace extensions |
| OLD | NEW |