summaryrefslogtreecommitdiff
path: root/chromium/extensions/common/manifest_handlers/shared_module_info.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/extensions/common/manifest_handlers/shared_module_info.cc')
-rw-r--r--chromium/extensions/common/manifest_handlers/shared_module_info.cc239
1 files changed, 239 insertions, 0 deletions
diff --git a/chromium/extensions/common/manifest_handlers/shared_module_info.cc b/chromium/extensions/common/manifest_handlers/shared_module_info.cc
new file mode 100644
index 00000000000..87c8e879d5e
--- /dev/null
+++ b/chromium/extensions/common/manifest_handlers/shared_module_info.cc
@@ -0,0 +1,239 @@
+// Copyright 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 "extensions/common/manifest_handlers/shared_module_info.h"
+
+#include <stddef.h>
+
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/version.h"
+#include "components/crx_file/id_util.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/permissions/permission_set.h"
+#include "extensions/common/permissions/permissions_data.h"
+
+namespace extensions {
+
+namespace keys = manifest_keys;
+namespace values = manifest_values;
+namespace errors = manifest_errors;
+
+namespace {
+
+const char kSharedModule[] = "shared_module";
+
+static base::LazyInstance<SharedModuleInfo> g_empty_shared_module_info =
+ LAZY_INSTANCE_INITIALIZER;
+
+const SharedModuleInfo& GetSharedModuleInfo(const Extension* extension) {
+ SharedModuleInfo* info = static_cast<SharedModuleInfo*>(
+ extension->GetManifestData(kSharedModule));
+ if (!info)
+ return g_empty_shared_module_info.Get();
+ return *info;
+}
+
+} // namespace
+
+SharedModuleInfo::SharedModuleInfo() {
+}
+
+SharedModuleInfo::~SharedModuleInfo() {
+}
+
+// static
+void SharedModuleInfo::ParseImportedPath(const std::string& path,
+ std::string* import_id,
+ std::string* import_relative_path) {
+ std::vector<std::string> tokens = base::SplitString(
+ path, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ if (tokens.size() > 2 && tokens[0] == kModulesDir &&
+ crx_file::id_util::IdIsValid(tokens[1])) {
+ *import_id = tokens[1];
+ *import_relative_path = tokens[2];
+ for (size_t i = 3; i < tokens.size(); ++i)
+ *import_relative_path += "/" + tokens[i];
+ }
+}
+
+// static
+bool SharedModuleInfo::IsImportedPath(const std::string& path) {
+ std::vector<std::string> tokens = base::SplitString(
+ path, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ if (tokens.size() > 2 && tokens[0] == kModulesDir &&
+ crx_file::id_util::IdIsValid(tokens[1])) {
+ return true;
+ }
+ return false;
+}
+
+// static
+bool SharedModuleInfo::IsSharedModule(const Extension* extension) {
+ CHECK(extension);
+ return extension->manifest()->is_shared_module();
+}
+
+// static
+bool SharedModuleInfo::IsExportAllowedByWhitelist(const Extension* extension,
+ const std::string& other_id) {
+ // Sanity check. In case the caller did not check |extension| to make sure it
+ // is a shared module, we do not want it to appear that the extension with
+ // |other_id| importing |extension| is valid.
+ if (!SharedModuleInfo::IsSharedModule(extension))
+ return false;
+ const SharedModuleInfo& info = GetSharedModuleInfo(extension);
+ if (info.export_whitelist_.empty())
+ return true;
+ if (info.export_whitelist_.find(other_id) != info.export_whitelist_.end())
+ return true;
+ return false;
+}
+
+// static
+bool SharedModuleInfo::ImportsExtensionById(const Extension* extension,
+ const std::string& other_id) {
+ const SharedModuleInfo& info = GetSharedModuleInfo(extension);
+ for (size_t i = 0; i < info.imports_.size(); i++) {
+ if (info.imports_[i].extension_id == other_id)
+ return true;
+ }
+ return false;
+}
+
+// static
+bool SharedModuleInfo::ImportsModules(const Extension* extension) {
+ return GetSharedModuleInfo(extension).imports_.size() > 0;
+}
+
+// static
+const std::vector<SharedModuleInfo::ImportInfo>& SharedModuleInfo::GetImports(
+ const Extension* extension) {
+ return GetSharedModuleInfo(extension).imports_;
+}
+
+bool SharedModuleInfo::Parse(const Extension* extension,
+ base::string16* error) {
+ bool has_import = extension->manifest()->HasKey(keys::kImport);
+ bool has_export = extension->manifest()->HasKey(keys::kExport);
+ if (!has_import && !has_export)
+ return true;
+
+ if (has_import && has_export) {
+ *error = base::ASCIIToUTF16(errors::kInvalidImportAndExport);
+ return false;
+ }
+
+ if (has_export) {
+ const base::DictionaryValue* export_value = NULL;
+ if (!extension->manifest()->GetDictionary(keys::kExport, &export_value)) {
+ *error = base::ASCIIToUTF16(errors::kInvalidExport);
+ return false;
+ }
+ if (export_value->HasKey(keys::kWhitelist)) {
+ const base::ListValue* whitelist = NULL;
+ if (!export_value->GetList(keys::kWhitelist, &whitelist)) {
+ *error = base::ASCIIToUTF16(errors::kInvalidExportWhitelist);
+ return false;
+ }
+ for (size_t i = 0; i < whitelist->GetSize(); ++i) {
+ std::string extension_id;
+ if (!whitelist->GetString(i, &extension_id) ||
+ !crx_file::id_util::IdIsValid(extension_id)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidExportWhitelistString, base::SizeTToString(i));
+ return false;
+ }
+ export_whitelist_.insert(extension_id);
+ }
+ }
+ }
+
+ if (has_import) {
+ const base::ListValue* import_list = NULL;
+ if (!extension->manifest()->GetList(keys::kImport, &import_list)) {
+ *error = base::ASCIIToUTF16(errors::kInvalidImport);
+ return false;
+ }
+ for (size_t i = 0; i < import_list->GetSize(); ++i) {
+ const base::DictionaryValue* import_entry = NULL;
+ if (!import_list->GetDictionary(i, &import_entry)) {
+ *error = base::ASCIIToUTF16(errors::kInvalidImport);
+ return false;
+ }
+ std::string extension_id;
+ imports_.push_back(ImportInfo());
+ if (!import_entry->GetString(keys::kId, &extension_id) ||
+ !crx_file::id_util::IdIsValid(extension_id)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidImportId,
+ base::SizeTToString(i));
+ return false;
+ }
+ imports_.back().extension_id = extension_id;
+ if (import_entry->HasKey(keys::kMinimumVersion)) {
+ std::string min_version;
+ if (!import_entry->GetString(keys::kMinimumVersion, &min_version)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidImportVersion, base::SizeTToString(i));
+ return false;
+ }
+ imports_.back().minimum_version = min_version;
+ Version v(min_version);
+ if (!v.IsValid()) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidImportVersion, base::SizeTToString(i));
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+
+SharedModuleHandler::SharedModuleHandler() {
+}
+
+SharedModuleHandler::~SharedModuleHandler() {
+}
+
+bool SharedModuleHandler::Parse(Extension* extension, base::string16* error) {
+ scoped_ptr<SharedModuleInfo> info(new SharedModuleInfo);
+ if (!info->Parse(extension, error))
+ return false;
+ extension->SetManifestData(kSharedModule, info.release());
+ return true;
+}
+
+bool SharedModuleHandler::Validate(
+ const Extension* extension,
+ std::string* error,
+ std::vector<InstallWarning>* warnings) const {
+ // Extensions that export resources should not have any permissions of their
+ // own, instead they rely on the permissions of the extensions which import
+ // them.
+ if (SharedModuleInfo::IsSharedModule(extension) &&
+ !extension->permissions_data()->active_permissions().IsEmpty()) {
+ *error = errors::kInvalidExportPermissions;
+ return false;
+ }
+ return true;
+}
+
+const std::vector<std::string> SharedModuleHandler::Keys() const {
+ static const char* keys[] = {
+ keys::kExport,
+ keys::kImport
+ };
+ return std::vector<std::string>(keys, keys + arraysize(keys));
+}
+
+} // namespace extensions