Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: chrome/common/extensions/manifest_handlers/shared_module_info.cc

Issue 13971005: Basic multi-module support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add browser test Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
6
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/string_util.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/utf_string_conversions.h"
12 #include "base/version.h"
13 #include "chrome/common/extensions/extension_constants.h"
14 #include "chrome/common/extensions/extension_manifest_constants.h"
15 #include "chrome/common/extensions/permissions/permission_set.h"
16 #include "extensions/common/error_utils.h"
17
18 using base::DictionaryValue;
19 namespace keys = extension_manifest_keys;
20 namespace values = extension_manifest_values;
21 namespace errors = extension_manifest_errors;
22
23 namespace extensions {
24
25 namespace {
26
27 const char kSharedModule[] = "shared_module";
28
29 static base::LazyInstance<SharedModuleInfo> g_empty_shared_module_info =
30 LAZY_INSTANCE_INITIALIZER;
31
32 const SharedModuleInfo& GetSharedModuleInfo(const Extension* extension) {
33 SharedModuleInfo* info = static_cast<SharedModuleInfo*>(
34 extension->GetManifestData(kSharedModule));
35 if (!info)
36 return g_empty_shared_module_info.Get();
37 return *info;
38 }
39
40 } // namespace
41
42 SharedModuleInfo::SharedModuleInfo() {
43 }
44
45 SharedModuleInfo::~SharedModuleInfo() {
46 }
47
48 // static
49 void SharedModuleInfo::ParseImportedPath(const std::string& path,
50 std::string* import_id,
51 std::string* import_relative_path) {
52 std::vector<std::string> tokens;
53 Tokenize(path, std::string("/"), &tokens);
54 if (tokens.size() > 2 && tokens[0] == extension_filenames::kModulesDir &&
55 Extension::IdIsValid(tokens[1])) {
56 *import_id = tokens[1];
57 *import_relative_path = tokens[2];
58 for (size_t i = 3; i < tokens.size(); ++i)
59 *import_relative_path += "/" + tokens[i];
60 }
61 }
62
63 // static
64 bool SharedModuleInfo::IsImportedPath(const std::string& path) {
65 std::vector<std::string> tokens;
66 Tokenize(path, std::string("/"), &tokens);
67 if (tokens.size() > 2 && tokens[0] == extension_filenames::kModulesDir &&
68 Extension::IdIsValid(tokens[1])) {
69 return true;
70 }
71 return false;
72 }
73
74 // static
75 bool SharedModuleInfo::IsSharedModule(const Extension* extension) {
76 CHECK(extension);
77 return extension->manifest()->is_shared_module();
78 }
79
80 // static
81 bool SharedModuleInfo::IsExportAllowed(const Extension* extension,
82 const std::string& relative_path) {
83 return GetSharedModuleInfo(extension).
84 exported_set_.MatchesURL(extension->url().Resolve(relative_path));
85 }
86
87 // static
88 bool SharedModuleInfo::ImportsExtensionById(const Extension* extension,
89 const std::string& other_id) {
90 const SharedModuleInfo& info = GetSharedModuleInfo(extension);
91 for (size_t i = 0; i < info.imports_.size(); i++) {
92 if (info.imports_[i].extension_id == other_id)
93 return true;
94 }
95 return false;
96 }
97
98 // static
99 bool SharedModuleInfo::ImportsModules(const Extension* extension) {
100 return GetSharedModuleInfo(extension).imports_.size() > 0;
101 }
102
103 // static
104 const std::vector<SharedModuleInfo::ImportInfo>& SharedModuleInfo::GetImports(
105 const Extension* extension) {
106 return GetSharedModuleInfo(extension).imports_;
107 }
108
109 bool SharedModuleInfo::Parse(const Extension* extension, string16* error) {
110 bool has_import = extension->manifest()->HasKey(keys::kImport);
111 bool has_export = extension->manifest()->HasKey(keys::kExport);
112 if (!has_import && !has_export)
113 return true;
114
115 if (has_import && has_export) {
116 *error = ASCIIToUTF16(errors::kInvalidImportAndExport);
117 return false;
118 }
119
120 if (has_export) {
121 const DictionaryValue* export_value = NULL;
122 if (!extension->manifest()->GetDictionary(keys::kExport, &export_value)) {
123 *error = ASCIIToUTF16(errors::kInvalidExport);
124 return false;
125 }
126 const ListValue* resources_list = NULL;
127 if (!export_value->GetList(keys::kResources, &resources_list)) {
128 *error = ASCIIToUTF16(errors::kInvalidExportResources);
129 return false;
130 }
131 for (size_t i = 0; i < resources_list->GetSize(); ++i) {
132 std::string resource_path;
133 if (!resources_list->GetString(i, &resource_path)) {
134 *error = ErrorUtils::FormatErrorMessageUTF16(
135 errors::kInvalidExportResourcesString, base::IntToString(i));
136 return false;
137 }
138 const GURL& resolved_path = extension->url().Resolve(resource_path);
139 if (!resolved_path.is_valid()) {
140 *error = ErrorUtils::FormatErrorMessageUTF16(
141 errors::kInvalidExportResourcesString, base::IntToString(i));
142 return false;
143 }
144 exported_set_.AddPattern(
145 URLPattern(URLPattern::SCHEME_EXTENSION, resolved_path.spec()));
146 }
147 }
148
149 if (has_import) {
150 const ListValue* import_list = NULL;
151 if (!extension->manifest()->GetList(keys::kImport, &import_list)) {
152 *error = ASCIIToUTF16(errors::kInvalidImport);
153 return false;
154 }
155 for (size_t i = 0; i < import_list->GetSize(); ++i) {
156 const DictionaryValue* import_entry = NULL;
157 if (!import_list->GetDictionary(i, &import_entry)) {
158 *error = ASCIIToUTF16(errors::kInvalidImport);
159 return false;
160 }
161 std::string extension_id;
162 imports_.push_back(ImportInfo());
163 if (!import_entry->GetString(keys::kId, &extension_id) ||
164 !Extension::IdIsValid(extension_id)) {
165 *error = ErrorUtils::FormatErrorMessageUTF16(
166 errors::kInvalidImportId, base::IntToString(i));
167 return false;
168 }
169 imports_.back().extension_id = extension_id;
170 if (import_entry->HasKey(keys::kMinimumVersion)) {
171 std::string min_version;
172 if (!import_entry->GetString(keys::kMinimumVersion, &min_version)) {
173 *error = ErrorUtils::FormatErrorMessageUTF16(
174 errors::kInvalidImportVersion, base::IntToString(i));
175 return false;
176 }
177 imports_.back().minimum_version = min_version;
178 Version v(min_version);
179 if (!v.IsValid()) {
180 *error = ErrorUtils::FormatErrorMessageUTF16(
181 errors::kInvalidImportVersion, base::IntToString(i));
182 return false;
183 }
184 }
185 }
186 }
187 return true;
188 }
189
190
191 SharedModuleHandler::SharedModuleHandler() {
192 }
193
194 SharedModuleHandler::~SharedModuleHandler() {
195 }
196
197 bool SharedModuleHandler::Parse(Extension* extension, string16* error) {
198 scoped_ptr<SharedModuleInfo> info(new SharedModuleInfo);
199 if (!info->Parse(extension, error))
200 return false;
201 extension->SetManifestData(kSharedModule, info.release());
202 return true;
203 }
204
205 bool SharedModuleHandler::Validate(
206 const Extension* extension,
207 std::string* error,
208 std::vector<InstallWarning>* warnings) const {
209 // Extensions that export resources should not have any permissions of their
210 // own, instead they rely on the permissions of the extensions which import
211 // them.
212 if (SharedModuleInfo::IsSharedModule(extension) &&
213 !extension->GetActivePermissions()->IsEmpty()) {
214 *error = errors::kInvalidExportPermissions;
215 return false;
216 }
217 return true;
218 }
219
220 const std::vector<std::string> SharedModuleHandler::Keys() const {
221 static const char* keys[] = {
222 keys::kExport,
223 keys::kImport
224 };
225 return std::vector<std::string>(keys, keys + arraysize(keys));
226 }
227
228 } // extensions
229
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698