| Index: chrome/common/extensions/extension.cc
|
| diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
|
| deleted file mode 100644
|
| index 71018ccd2b0605a11fadea93f17237574c6d3557..0000000000000000000000000000000000000000
|
| --- a/chrome/common/extensions/extension.cc
|
| +++ /dev/null
|
| @@ -1,794 +0,0 @@
|
| -// Copyright (c) 2013 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 "chrome/common/extensions/extension.h"
|
| -
|
| -#include "base/base64.h"
|
| -#include "base/basictypes.h"
|
| -#include "base/command_line.h"
|
| -#include "base/files/file_path.h"
|
| -#include "base/i18n/rtl.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/singleton.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/string16.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_piece.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/values.h"
|
| -#include "base/version.h"
|
| -#include "chrome/common/extensions/extension_constants.h"
|
| -#include "chrome/common/extensions/permissions/permissions_data.h"
|
| -#include "content/public/common/url_constants.h"
|
| -#include "extensions/common/constants.h"
|
| -#include "extensions/common/error_utils.h"
|
| -#include "extensions/common/id_util.h"
|
| -#include "extensions/common/manifest.h"
|
| -#include "extensions/common/manifest_constants.h"
|
| -#include "extensions/common/manifest_handler.h"
|
| -#include "extensions/common/permissions/api_permission_set.h"
|
| -#include "extensions/common/permissions/permission_set.h"
|
| -#include "extensions/common/permissions/permissions_info.h"
|
| -#include "extensions/common/switches.h"
|
| -#include "extensions/common/url_pattern_set.h"
|
| -#include "grit/chromium_strings.h"
|
| -#include "grit/theme_resources.h"
|
| -#include "net/base/net_util.h"
|
| -#include "third_party/skia/include/core/SkBitmap.h"
|
| -#include "url/url_util.h"
|
| -
|
| -#if defined(OS_WIN)
|
| -#include "grit/generated_resources.h"
|
| -#endif
|
| -
|
| -namespace extensions {
|
| -
|
| -namespace keys = manifest_keys;
|
| -namespace values = manifest_values;
|
| -namespace errors = manifest_errors;
|
| -
|
| -namespace {
|
| -
|
| -const int kModernManifestVersion = 2;
|
| -const int kPEMOutputColumns = 65;
|
| -
|
| -// KEY MARKERS
|
| -const char kKeyBeginHeaderMarker[] = "-----BEGIN";
|
| -const char kKeyBeginFooterMarker[] = "-----END";
|
| -const char kKeyInfoEndMarker[] = "KEY-----";
|
| -const char kPublic[] = "PUBLIC";
|
| -const char kPrivate[] = "PRIVATE";
|
| -
|
| -bool ContainsReservedCharacters(const base::FilePath& path) {
|
| - // We should disallow backslash '\\' as file path separator even on Windows,
|
| - // because the backslash is not regarded as file path separator on Linux/Mac.
|
| - // Extensions are cross-platform.
|
| - // Since FilePath uses backslash '\\' as file path separator on Windows, so we
|
| - // need to check manually.
|
| - if (path.value().find('\\') != path.value().npos)
|
| - return true;
|
| - return !net::IsSafePortableRelativePath(path);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -const char Extension::kMimeType[] = "application/x-chrome-extension";
|
| -
|
| -const int Extension::kValidWebExtentSchemes =
|
| - URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS;
|
| -
|
| -const int Extension::kValidHostPermissionSchemes = URLPattern::SCHEME_CHROMEUI |
|
| - URLPattern::SCHEME_HTTP |
|
| - URLPattern::SCHEME_HTTPS |
|
| - URLPattern::SCHEME_FILE |
|
| - URLPattern::SCHEME_FTP;
|
| -
|
| -//
|
| -// Extension
|
| -//
|
| -
|
| -// static
|
| -scoped_refptr<Extension> Extension::Create(const base::FilePath& path,
|
| - Manifest::Location location,
|
| - const base::DictionaryValue& value,
|
| - int flags,
|
| - std::string* utf8_error) {
|
| - return Extension::Create(path,
|
| - location,
|
| - value,
|
| - flags,
|
| - std::string(), // ID is ignored if empty.
|
| - utf8_error);
|
| -}
|
| -
|
| -// TODO(sungguk): Continue removing std::string errors and replacing
|
| -// with string16. See http://crbug.com/71980.
|
| -scoped_refptr<Extension> Extension::Create(const base::FilePath& path,
|
| - Manifest::Location location,
|
| - const base::DictionaryValue& value,
|
| - int flags,
|
| - const std::string& explicit_id,
|
| - std::string* utf8_error) {
|
| - DCHECK(utf8_error);
|
| - string16 error;
|
| - scoped_ptr<extensions::Manifest> manifest(
|
| - new extensions::Manifest(
|
| - location, scoped_ptr<base::DictionaryValue>(value.DeepCopy())));
|
| -
|
| - if (!InitExtensionID(manifest.get(), path, explicit_id, flags, &error)) {
|
| - *utf8_error = UTF16ToUTF8(error);
|
| - return NULL;
|
| - }
|
| -
|
| - std::vector<InstallWarning> install_warnings;
|
| - if (!manifest->ValidateManifest(utf8_error, &install_warnings)) {
|
| - return NULL;
|
| - }
|
| -
|
| - scoped_refptr<Extension> extension = new Extension(path, manifest.Pass());
|
| - extension->install_warnings_.swap(install_warnings);
|
| -
|
| - if (!extension->InitFromValue(flags, &error)) {
|
| - *utf8_error = UTF16ToUTF8(error);
|
| - return NULL;
|
| - }
|
| -
|
| - return extension;
|
| -}
|
| -
|
| -// static
|
| -bool Extension::IdIsValid(const std::string& id) {
|
| - // Verify that the id is legal.
|
| - if (id.size() != (id_util::kIdSize * 2))
|
| - return false;
|
| -
|
| - // We only support lowercase IDs, because IDs can be used as URL components
|
| - // (where GURL will lowercase it).
|
| - std::string temp = StringToLowerASCII(id);
|
| - for (size_t i = 0; i < temp.size(); i++)
|
| - if (temp[i] < 'a' || temp[i] > 'p')
|
| - return false;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -Manifest::Type Extension::GetType() const {
|
| - return converted_from_user_script() ?
|
| - Manifest::TYPE_USER_SCRIPT : manifest_->type();
|
| -}
|
| -
|
| -// static
|
| -GURL Extension::GetResourceURL(const GURL& extension_url,
|
| - const std::string& relative_path) {
|
| - DCHECK(extension_url.SchemeIs(extensions::kExtensionScheme));
|
| - DCHECK_EQ("/", extension_url.path());
|
| -
|
| - std::string path = relative_path;
|
| -
|
| - // If the relative path starts with "/", it is "absolute" relative to the
|
| - // extension base directory, but extension_url is already specified to refer
|
| - // to that base directory, so strip the leading "/" if present.
|
| - if (relative_path.size() > 0 && relative_path[0] == '/')
|
| - path = relative_path.substr(1);
|
| -
|
| - GURL ret_val = GURL(extension_url.spec() + path);
|
| - DCHECK(StartsWithASCII(ret_val.spec(), extension_url.spec(), false));
|
| -
|
| - return ret_val;
|
| -}
|
| -
|
| -bool Extension::ResourceMatches(const URLPatternSet& pattern_set,
|
| - const std::string& resource) const {
|
| - return pattern_set.MatchesURL(extension_url_.Resolve(resource));
|
| -}
|
| -
|
| -ExtensionResource Extension::GetResource(
|
| - const std::string& relative_path) const {
|
| - std::string new_path = relative_path;
|
| - // We have some legacy data where resources have leading slashes.
|
| - // See: http://crbug.com/121164
|
| - if (!new_path.empty() && new_path.at(0) == '/')
|
| - new_path.erase(0, 1);
|
| - base::FilePath relative_file_path = base::FilePath::FromUTF8Unsafe(new_path);
|
| - if (ContainsReservedCharacters(relative_file_path))
|
| - return ExtensionResource();
|
| - ExtensionResource r(id(), path(), relative_file_path);
|
| - if ((creation_flags() & Extension::FOLLOW_SYMLINKS_ANYWHERE)) {
|
| - r.set_follow_symlinks_anywhere();
|
| - }
|
| - return r;
|
| -}
|
| -
|
| -ExtensionResource Extension::GetResource(
|
| - const base::FilePath& relative_file_path) const {
|
| - if (ContainsReservedCharacters(relative_file_path))
|
| - return ExtensionResource();
|
| - ExtensionResource r(id(), path(), relative_file_path);
|
| - if ((creation_flags() & Extension::FOLLOW_SYMLINKS_ANYWHERE)) {
|
| - r.set_follow_symlinks_anywhere();
|
| - }
|
| - return r;
|
| -}
|
| -
|
| -// TODO(rafaelw): Move ParsePEMKeyBytes, ProducePEM & FormatPEMForOutput to a
|
| -// util class in base:
|
| -// http://code.google.com/p/chromium/issues/detail?id=13572
|
| -// static
|
| -bool Extension::ParsePEMKeyBytes(const std::string& input,
|
| - std::string* output) {
|
| - DCHECK(output);
|
| - if (!output)
|
| - return false;
|
| - if (input.length() == 0)
|
| - return false;
|
| -
|
| - std::string working = input;
|
| - if (StartsWithASCII(working, kKeyBeginHeaderMarker, true)) {
|
| - working = CollapseWhitespaceASCII(working, true);
|
| - size_t header_pos = working.find(kKeyInfoEndMarker,
|
| - sizeof(kKeyBeginHeaderMarker) - 1);
|
| - if (header_pos == std::string::npos)
|
| - return false;
|
| - size_t start_pos = header_pos + sizeof(kKeyInfoEndMarker) - 1;
|
| - size_t end_pos = working.rfind(kKeyBeginFooterMarker);
|
| - if (end_pos == std::string::npos)
|
| - return false;
|
| - if (start_pos >= end_pos)
|
| - return false;
|
| -
|
| - working = working.substr(start_pos, end_pos - start_pos);
|
| - if (working.length() == 0)
|
| - return false;
|
| - }
|
| -
|
| - return base::Base64Decode(working, output);
|
| -}
|
| -
|
| -// static
|
| -bool Extension::ProducePEM(const std::string& input, std::string* output) {
|
| - DCHECK(output);
|
| - return (input.length() == 0) ? false : base::Base64Encode(input, output);
|
| -}
|
| -
|
| -// static
|
| -bool Extension::FormatPEMForFileOutput(const std::string& input,
|
| - std::string* output,
|
| - bool is_public) {
|
| - DCHECK(output);
|
| - if (input.length() == 0)
|
| - return false;
|
| - *output = "";
|
| - output->append(kKeyBeginHeaderMarker);
|
| - output->append(" ");
|
| - output->append(is_public ? kPublic : kPrivate);
|
| - output->append(" ");
|
| - output->append(kKeyInfoEndMarker);
|
| - output->append("\n");
|
| - for (size_t i = 0; i < input.length(); ) {
|
| - int slice = std::min<int>(input.length() - i, kPEMOutputColumns);
|
| - output->append(input.substr(i, slice));
|
| - output->append("\n");
|
| - i += slice;
|
| - }
|
| - output->append(kKeyBeginFooterMarker);
|
| - output->append(" ");
|
| - output->append(is_public ? kPublic : kPrivate);
|
| - output->append(" ");
|
| - output->append(kKeyInfoEndMarker);
|
| - output->append("\n");
|
| -
|
| - return true;
|
| -}
|
| -
|
| -// static
|
| -GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) {
|
| - return GURL(std::string(extensions::kExtensionScheme) +
|
| - content::kStandardSchemeSeparator + extension_id + "/");
|
| -}
|
| -
|
| -bool Extension::HasAPIPermission(APIPermission::ID permission) const {
|
| - return PermissionsData::HasAPIPermission(this, permission);
|
| -}
|
| -
|
| -bool Extension::HasAPIPermission(const std::string& permission_name) const {
|
| - return PermissionsData::HasAPIPermission(this, permission_name);
|
| -}
|
| -
|
| -scoped_refptr<const PermissionSet> Extension::GetActivePermissions() const {
|
| - return PermissionsData::GetActivePermissions(this);
|
| -}
|
| -
|
| -bool Extension::ShowConfigureContextMenus() const {
|
| - // Don't show context menu for component extensions. We might want to show
|
| - // options for component extension button but now there is no component
|
| - // extension with options. All other menu items like uninstall have
|
| - // no sense for component extensions.
|
| - return location() != Manifest::COMPONENT;
|
| -}
|
| -
|
| -bool Extension::OverlapsWithOrigin(const GURL& origin) const {
|
| - if (url() == origin)
|
| - return true;
|
| -
|
| - if (web_extent().is_empty())
|
| - return false;
|
| -
|
| - // Note: patterns and extents ignore port numbers.
|
| - URLPattern origin_only_pattern(kValidWebExtentSchemes);
|
| - if (!origin_only_pattern.SetScheme(origin.scheme()))
|
| - return false;
|
| - origin_only_pattern.SetHost(origin.host());
|
| - origin_only_pattern.SetPath("/*");
|
| -
|
| - URLPatternSet origin_only_pattern_list;
|
| - origin_only_pattern_list.AddPattern(origin_only_pattern);
|
| -
|
| - return web_extent().OverlapsWith(origin_only_pattern_list);
|
| -}
|
| -
|
| -bool Extension::RequiresSortOrdinal() const {
|
| - return is_app() && (display_in_launcher_ || display_in_new_tab_page_);
|
| -}
|
| -
|
| -bool Extension::ShouldDisplayInAppLauncher() const {
|
| - // Only apps should be displayed in the launcher.
|
| - return is_app() && display_in_launcher_;
|
| -}
|
| -
|
| -bool Extension::ShouldDisplayInNewTabPage() const {
|
| - // Only apps should be displayed on the NTP.
|
| - return is_app() && display_in_new_tab_page_;
|
| -}
|
| -
|
| -bool Extension::ShouldDisplayInExtensionSettings() const {
|
| - // Don't show for themes since the settings UI isn't really useful for them.
|
| - if (is_theme())
|
| - return false;
|
| -
|
| - // Don't show component extensions and invisible apps.
|
| - if (ShouldNotBeVisible())
|
| - return false;
|
| -
|
| - // Always show unpacked extensions and apps.
|
| - if (Manifest::IsUnpackedLocation(location()))
|
| - return true;
|
| -
|
| - // Unless they are unpacked, never show hosted apps. Note: We intentionally
|
| - // show packaged apps and platform apps because there are some pieces of
|
| - // functionality that are only available in chrome://extensions/ but which
|
| - // are needed for packaged and platform apps. For example, inspecting
|
| - // background pages. See http://crbug.com/116134.
|
| - if (is_hosted_app())
|
| - return false;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::ShouldNotBeVisible() const {
|
| - // Don't show component extensions because they are only extensions as an
|
| - // implementation detail of Chrome.
|
| - if (location() == Manifest::COMPONENT &&
|
| - !CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kShowComponentExtensionOptions)) {
|
| - return true;
|
| - }
|
| -
|
| - // Always show unpacked extensions and apps.
|
| - if (Manifest::IsUnpackedLocation(location()))
|
| - return false;
|
| -
|
| - // Don't show apps that aren't visible in either launcher or ntp.
|
| - if (is_app() && !ShouldDisplayInAppLauncher() && !ShouldDisplayInNewTabPage())
|
| - return true;
|
| -
|
| - return false;
|
| -}
|
| -
|
| -Extension::ManifestData* Extension::GetManifestData(const std::string& key)
|
| - const {
|
| - DCHECK(finished_parsing_manifest_ || thread_checker_.CalledOnValidThread());
|
| - ManifestDataMap::const_iterator iter = manifest_data_.find(key);
|
| - if (iter != manifest_data_.end())
|
| - return iter->second.get();
|
| - return NULL;
|
| -}
|
| -
|
| -void Extension::SetManifestData(const std::string& key,
|
| - Extension::ManifestData* data) {
|
| - DCHECK(!finished_parsing_manifest_ && thread_checker_.CalledOnValidThread());
|
| - manifest_data_[key] = linked_ptr<ManifestData>(data);
|
| -}
|
| -
|
| -Manifest::Location Extension::location() const {
|
| - return manifest_->location();
|
| -}
|
| -
|
| -const std::string& Extension::id() const {
|
| - return manifest_->extension_id();
|
| -}
|
| -
|
| -const std::string Extension::VersionString() const {
|
| - return version()->GetString();
|
| -}
|
| -
|
| -void Extension::AddInstallWarning(const InstallWarning& new_warning) {
|
| - install_warnings_.push_back(new_warning);
|
| -}
|
| -
|
| -void Extension::AddInstallWarnings(
|
| - const std::vector<InstallWarning>& new_warnings) {
|
| - install_warnings_.insert(install_warnings_.end(),
|
| - new_warnings.begin(), new_warnings.end());
|
| -}
|
| -
|
| -bool Extension::is_app() const {
|
| - return manifest_->is_app();
|
| -}
|
| -
|
| -bool Extension::is_platform_app() const {
|
| - return manifest_->is_platform_app();
|
| -}
|
| -
|
| -bool Extension::is_hosted_app() const {
|
| - return manifest()->is_hosted_app();
|
| -}
|
| -
|
| -bool Extension::is_legacy_packaged_app() const {
|
| - return manifest()->is_legacy_packaged_app();
|
| -}
|
| -
|
| -bool Extension::is_extension() const {
|
| - return manifest()->is_extension();
|
| -}
|
| -
|
| -bool Extension::can_be_incognito_enabled() const {
|
| - // Only component platform apps are supported in incognito.
|
| - return !is_platform_app() || location() == Manifest::COMPONENT;
|
| -}
|
| -
|
| -bool Extension::force_incognito_enabled() const {
|
| - return PermissionsData::HasAPIPermission(this, APIPermission::kProxy);
|
| -}
|
| -
|
| -void Extension::AddWebExtentPattern(const URLPattern& pattern) {
|
| - extent_.AddPattern(pattern);
|
| -}
|
| -
|
| -bool Extension::is_theme() const {
|
| - return manifest()->is_theme();
|
| -}
|
| -
|
| -// static
|
| -bool Extension::InitExtensionID(extensions::Manifest* manifest,
|
| - const base::FilePath& path,
|
| - const std::string& explicit_id,
|
| - int creation_flags,
|
| - string16* error) {
|
| - if (!explicit_id.empty()) {
|
| - manifest->set_extension_id(explicit_id);
|
| - return true;
|
| - }
|
| -
|
| - if (manifest->HasKey(keys::kPublicKey)) {
|
| - std::string public_key;
|
| - std::string public_key_bytes;
|
| - if (!manifest->GetString(keys::kPublicKey, &public_key) ||
|
| - !ParsePEMKeyBytes(public_key, &public_key_bytes)) {
|
| - *error = ASCIIToUTF16(errors::kInvalidKey);
|
| - return false;
|
| - }
|
| - std::string extension_id = id_util::GenerateId(public_key_bytes);
|
| - manifest->set_extension_id(extension_id);
|
| - return true;
|
| - }
|
| -
|
| - if (creation_flags & REQUIRE_KEY) {
|
| - *error = ASCIIToUTF16(errors::kInvalidKey);
|
| - return false;
|
| - } else {
|
| - // If there is a path, we generate the ID from it. This is useful for
|
| - // development mode, because it keeps the ID stable across restarts and
|
| - // reloading the extension.
|
| - std::string extension_id = id_util::GenerateIdForPath(path);
|
| - if (extension_id.empty()) {
|
| - NOTREACHED() << "Could not create ID from path.";
|
| - return false;
|
| - }
|
| - manifest->set_extension_id(extension_id);
|
| - return true;
|
| - }
|
| -}
|
| -
|
| -Extension::Extension(const base::FilePath& path,
|
| - scoped_ptr<extensions::Manifest> manifest)
|
| - : manifest_version_(0),
|
| - converted_from_user_script_(false),
|
| - manifest_(manifest.release()),
|
| - finished_parsing_manifest_(false),
|
| - display_in_launcher_(true),
|
| - display_in_new_tab_page_(true),
|
| - wants_file_access_(false),
|
| - creation_flags_(0) {
|
| - DCHECK(path.empty() || path.IsAbsolute());
|
| - path_ = id_util::MaybeNormalizePath(path);
|
| -}
|
| -
|
| -Extension::~Extension() {
|
| -}
|
| -
|
| -bool Extension::InitFromValue(int flags, string16* error) {
|
| - DCHECK(error);
|
| -
|
| - creation_flags_ = flags;
|
| -
|
| - // Important to load manifest version first because many other features
|
| - // depend on its value.
|
| - if (!LoadManifestVersion(error))
|
| - return false;
|
| -
|
| - if (!LoadRequiredFeatures(error))
|
| - return false;
|
| -
|
| - // We don't need to validate because InitExtensionID already did that.
|
| - manifest_->GetString(keys::kPublicKey, &public_key_);
|
| -
|
| - extension_url_ = Extension::GetBaseURLFromExtensionId(id());
|
| -
|
| - // Load App settings. LoadExtent at least has to be done before
|
| - // ParsePermissions(), because the valid permissions depend on what type of
|
| - // package this is.
|
| - if (is_app() && !LoadAppFeatures(error))
|
| - return false;
|
| -
|
| - permissions_data_.reset(new PermissionsData);
|
| - if (!permissions_data_->ParsePermissions(this, error))
|
| - return false;
|
| -
|
| - if (manifest_->HasKey(keys::kConvertedFromUserScript)) {
|
| - manifest_->GetBoolean(keys::kConvertedFromUserScript,
|
| - &converted_from_user_script_);
|
| - }
|
| -
|
| - if (!LoadSharedFeatures(error))
|
| - return false;
|
| -
|
| - finished_parsing_manifest_ = true;
|
| -
|
| - permissions_data_->InitializeManifestPermissions(this);
|
| - permissions_data_->FinalizePermissions(this);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadRequiredFeatures(string16* error) {
|
| - if (!LoadName(error) ||
|
| - !LoadVersion(error))
|
| - return false;
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadName(string16* error) {
|
| - string16 localized_name;
|
| - if (!manifest_->GetString(keys::kName, &localized_name)) {
|
| - *error = ASCIIToUTF16(errors::kInvalidName);
|
| - return false;
|
| - }
|
| - non_localized_name_ = UTF16ToUTF8(localized_name);
|
| - base::i18n::AdjustStringForLocaleDirection(&localized_name);
|
| - name_ = UTF16ToUTF8(localized_name);
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadVersion(string16* error) {
|
| - std::string version_str;
|
| - if (!manifest_->GetString(keys::kVersion, &version_str)) {
|
| - *error = ASCIIToUTF16(errors::kInvalidVersion);
|
| - return false;
|
| - }
|
| - version_.reset(new Version(version_str));
|
| - if (!version_->IsValid() || version_->components().size() > 4) {
|
| - *error = ASCIIToUTF16(errors::kInvalidVersion);
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadAppFeatures(string16* error) {
|
| - if (!LoadExtent(keys::kWebURLs, &extent_,
|
| - errors::kInvalidWebURLs, errors::kInvalidWebURL, error)) {
|
| - return false;
|
| - }
|
| - if (manifest_->HasKey(keys::kDisplayInLauncher) &&
|
| - !manifest_->GetBoolean(keys::kDisplayInLauncher, &display_in_launcher_)) {
|
| - *error = ASCIIToUTF16(errors::kInvalidDisplayInLauncher);
|
| - return false;
|
| - }
|
| - if (manifest_->HasKey(keys::kDisplayInNewTabPage)) {
|
| - if (!manifest_->GetBoolean(keys::kDisplayInNewTabPage,
|
| - &display_in_new_tab_page_)) {
|
| - *error = ASCIIToUTF16(errors::kInvalidDisplayInNewTabPage);
|
| - return false;
|
| - }
|
| - } else {
|
| - // Inherit default from display_in_launcher property.
|
| - display_in_new_tab_page_ = display_in_launcher_;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadExtent(const char* key,
|
| - URLPatternSet* extent,
|
| - const char* list_error,
|
| - const char* value_error,
|
| - string16* error) {
|
| - const base::Value* temp_pattern_value = NULL;
|
| - if (!manifest_->Get(key, &temp_pattern_value))
|
| - return true;
|
| -
|
| - const base::ListValue* pattern_list = NULL;
|
| - if (!temp_pattern_value->GetAsList(&pattern_list)) {
|
| - *error = ASCIIToUTF16(list_error);
|
| - return false;
|
| - }
|
| -
|
| - for (size_t i = 0; i < pattern_list->GetSize(); ++i) {
|
| - std::string pattern_string;
|
| - if (!pattern_list->GetString(i, &pattern_string)) {
|
| - *error = ErrorUtils::FormatErrorMessageUTF16(value_error,
|
| - base::UintToString(i),
|
| - errors::kExpectString);
|
| - return false;
|
| - }
|
| -
|
| - URLPattern pattern(kValidWebExtentSchemes);
|
| - URLPattern::ParseResult parse_result = pattern.Parse(pattern_string);
|
| - if (parse_result == URLPattern::PARSE_ERROR_EMPTY_PATH) {
|
| - pattern_string += "/";
|
| - parse_result = pattern.Parse(pattern_string);
|
| - }
|
| -
|
| - if (parse_result != URLPattern::PARSE_SUCCESS) {
|
| - *error = ErrorUtils::FormatErrorMessageUTF16(
|
| - value_error,
|
| - base::UintToString(i),
|
| - URLPattern::GetParseResultString(parse_result));
|
| - return false;
|
| - }
|
| -
|
| - // Do not allow authors to claim "<all_urls>".
|
| - if (pattern.match_all_urls()) {
|
| - *error = ErrorUtils::FormatErrorMessageUTF16(
|
| - value_error,
|
| - base::UintToString(i),
|
| - errors::kCannotClaimAllURLsInExtent);
|
| - return false;
|
| - }
|
| -
|
| - // Do not allow authors to claim "*" for host.
|
| - if (pattern.host().empty()) {
|
| - *error = ErrorUtils::FormatErrorMessageUTF16(
|
| - value_error,
|
| - base::UintToString(i),
|
| - errors::kCannotClaimAllHostsInExtent);
|
| - return false;
|
| - }
|
| -
|
| - // We do not allow authors to put wildcards in their paths. Instead, we
|
| - // imply one at the end.
|
| - if (pattern.path().find('*') != std::string::npos) {
|
| - *error = ErrorUtils::FormatErrorMessageUTF16(
|
| - value_error,
|
| - base::UintToString(i),
|
| - errors::kNoWildCardsInPaths);
|
| - return false;
|
| - }
|
| - pattern.SetPath(pattern.path() + '*');
|
| -
|
| - extent->AddPattern(pattern);
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadSharedFeatures(string16* error) {
|
| - if (!LoadDescription(error) ||
|
| - !ManifestHandler::ParseExtension(this, error) ||
|
| - !LoadShortName(error))
|
| - return false;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadDescription(string16* error) {
|
| - if (manifest_->HasKey(keys::kDescription) &&
|
| - !manifest_->GetString(keys::kDescription, &description_)) {
|
| - *error = ASCIIToUTF16(errors::kInvalidDescription);
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadManifestVersion(string16* error) {
|
| - // Get the original value out of the dictionary so that we can validate it
|
| - // more strictly.
|
| - if (manifest_->value()->HasKey(keys::kManifestVersion)) {
|
| - int manifest_version = 1;
|
| - if (!manifest_->GetInteger(keys::kManifestVersion, &manifest_version) ||
|
| - manifest_version < 1) {
|
| - *error = ASCIIToUTF16(errors::kInvalidManifestVersion);
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - manifest_version_ = manifest_->GetManifestVersion();
|
| - if (manifest_version_ < kModernManifestVersion &&
|
| - ((creation_flags_ & REQUIRE_MODERN_MANIFEST_VERSION &&
|
| - !CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kAllowLegacyExtensionManifests)) ||
|
| - GetType() == Manifest::TYPE_PLATFORM_APP)) {
|
| - *error = ErrorUtils::FormatErrorMessageUTF16(
|
| - errors::kInvalidManifestVersionOld,
|
| - base::IntToString(kModernManifestVersion),
|
| - is_platform_app() ? "apps" : "extensions");
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool Extension::LoadShortName(string16* error) {
|
| - if (manifest_->HasKey(keys::kShortName)) {
|
| - string16 localized_short_name;
|
| - if (!manifest_->GetString(keys::kShortName, &localized_short_name) ||
|
| - localized_short_name.empty()) {
|
| - *error = ASCIIToUTF16(errors::kInvalidShortName);
|
| - return false;
|
| - }
|
| -
|
| - base::i18n::AdjustStringForLocaleDirection(&localized_short_name);
|
| - short_name_ = UTF16ToUTF8(localized_short_name);
|
| - } else {
|
| - short_name_ = name_;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -ExtensionInfo::ExtensionInfo(const base::DictionaryValue* manifest,
|
| - const std::string& id,
|
| - const base::FilePath& path,
|
| - Manifest::Location location)
|
| - : extension_id(id),
|
| - extension_path(path),
|
| - extension_location(location) {
|
| - if (manifest)
|
| - extension_manifest.reset(manifest->DeepCopy());
|
| -}
|
| -
|
| -ExtensionInfo::~ExtensionInfo() {}
|
| -
|
| -InstalledExtensionInfo::InstalledExtensionInfo(
|
| - const Extension* extension,
|
| - bool is_update,
|
| - const std::string& old_name)
|
| - : extension(extension),
|
| - is_update(is_update),
|
| - old_name(old_name) {}
|
| -
|
| -UnloadedExtensionInfo::UnloadedExtensionInfo(
|
| - const Extension* extension,
|
| - UnloadedExtensionInfo::Reason reason)
|
| - : reason(reason),
|
| - extension(extension) {}
|
| -
|
| -UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
|
| - const Extension* extension,
|
| - const PermissionSet* permissions,
|
| - Reason reason)
|
| - : reason(reason),
|
| - extension(extension),
|
| - permissions(permissions) {}
|
| -
|
| -} // namespace extensions
|
|
|