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 "extensions/common/manifest_handler.h"
6
7 #include <map>
8
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "extensions/common/extension.h"
12 #include "extensions/common/permissions/manifest_permission.h"
13 #include "extensions/common/permissions/manifest_permission_set.h"
14
15 namespace extensions {
16
17 namespace {
18
19 static base::LazyInstance<ManifestHandlerRegistry> g_registry =
20 LAZY_INSTANCE_INITIALIZER;
21 static ManifestHandlerRegistry* g_registry_override = NULL;
22
GetRegistry()23 ManifestHandlerRegistry* GetRegistry() {
24 if (!g_registry_override)
25 return g_registry.Pointer();
26 return g_registry_override;
27 }
28
29 } // namespace
30
ManifestHandler()31 ManifestHandler::ManifestHandler() {
32 }
33
~ManifestHandler()34 ManifestHandler::~ManifestHandler() {
35 }
36
Validate(const Extension * extension,std::string * error,std::vector<InstallWarning> * warnings) const37 bool ManifestHandler::Validate(const Extension* extension,
38 std::string* error,
39 std::vector<InstallWarning>* warnings) const {
40 return true;
41 }
42
AlwaysParseForType(Manifest::Type type) const43 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
44 return false;
45 }
46
AlwaysValidateForType(Manifest::Type type) const47 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
48 return false;
49 }
50
PrerequisiteKeys() const51 const std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
52 return std::vector<std::string>();
53 }
54
Register()55 void ManifestHandler::Register() {
56 linked_ptr<ManifestHandler> this_linked(this);
57 const std::vector<std::string> keys = Keys();
58 for (size_t i = 0; i < keys.size(); ++i)
59 GetRegistry()->RegisterManifestHandler(keys[i], this_linked);
60 }
61
CreatePermission()62 ManifestPermission* ManifestHandler::CreatePermission() {
63 return NULL;
64 }
65
CreateInitialRequiredPermission(const Extension * extension)66 ManifestPermission* ManifestHandler::CreateInitialRequiredPermission(
67 const Extension* extension) {
68 return NULL;
69 }
70
71 // static
FinalizeRegistration()72 void ManifestHandler::FinalizeRegistration() {
73 GetRegistry()->Finalize();
74 }
75
76 // static
IsRegistrationFinalized()77 bool ManifestHandler::IsRegistrationFinalized() {
78 return GetRegistry()->is_finalized_;
79 }
80
81 // static
ParseExtension(Extension * extension,string16 * error)82 bool ManifestHandler::ParseExtension(Extension* extension, string16* error) {
83 return GetRegistry()->ParseExtension(extension, error);
84 }
85
86 // static
ValidateExtension(const Extension * extension,std::string * error,std::vector<InstallWarning> * warnings)87 bool ManifestHandler::ValidateExtension(const Extension* extension,
88 std::string* error,
89 std::vector<InstallWarning>* warnings) {
90 return GetRegistry()->ValidateExtension(extension, error, warnings);
91 }
92
93 // static
CreatePermission(const std::string & name)94 ManifestPermission* ManifestHandler::CreatePermission(const std::string& name) {
95 return GetRegistry()->CreatePermission(name);
96 }
97
98 // static
AddExtensionInitialRequiredPermissions(const Extension * extension,ManifestPermissionSet * permission_set)99 void ManifestHandler::AddExtensionInitialRequiredPermissions(
100 const Extension* extension, ManifestPermissionSet* permission_set) {
101 return GetRegistry()->AddExtensionInitialRequiredPermissions(extension,
102 permission_set);
103 }
104
105 // static
SingleKey(const std::string & key)106 const std::vector<std::string> ManifestHandler::SingleKey(
107 const std::string& key) {
108 return std::vector<std::string>(1, key);
109 }
110
ManifestHandlerRegistry()111 ManifestHandlerRegistry::ManifestHandlerRegistry() : is_finalized_(false) {
112 }
113
~ManifestHandlerRegistry()114 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
115 }
116
Finalize()117 void ManifestHandlerRegistry::Finalize() {
118 CHECK(!is_finalized_);
119 SortManifestHandlers();
120 is_finalized_ = true;
121 }
122
RegisterManifestHandler(const std::string & key,linked_ptr<ManifestHandler> handler)123 void ManifestHandlerRegistry::RegisterManifestHandler(
124 const std::string& key, linked_ptr<ManifestHandler> handler) {
125 CHECK(!is_finalized_);
126 handlers_[key] = handler;
127 }
128
ParseExtension(Extension * extension,string16 * error)129 bool ManifestHandlerRegistry::ParseExtension(Extension* extension,
130 string16* error) {
131 std::map<int, ManifestHandler*> handlers_by_priority;
132 for (ManifestHandlerMap::iterator iter = handlers_.begin();
133 iter != handlers_.end(); ++iter) {
134 ManifestHandler* handler = iter->second.get();
135 if (extension->manifest()->HasPath(iter->first) ||
136 handler->AlwaysParseForType(extension->GetType())) {
137 handlers_by_priority[priority_map_[handler]] = handler;
138 }
139 }
140 for (std::map<int, ManifestHandler*>::iterator iter =
141 handlers_by_priority.begin();
142 iter != handlers_by_priority.end(); ++iter) {
143 if (!(iter->second)->Parse(extension, error))
144 return false;
145 }
146 return true;
147 }
148
ValidateExtension(const Extension * extension,std::string * error,std::vector<InstallWarning> * warnings)149 bool ManifestHandlerRegistry::ValidateExtension(
150 const Extension* extension,
151 std::string* error,
152 std::vector<InstallWarning>* warnings) {
153 std::set<ManifestHandler*> handlers;
154 for (ManifestHandlerMap::iterator iter = handlers_.begin();
155 iter != handlers_.end(); ++iter) {
156 ManifestHandler* handler = iter->second.get();
157 if (extension->manifest()->HasPath(iter->first) ||
158 handler->AlwaysValidateForType(extension->GetType())) {
159 handlers.insert(handler);
160 }
161 }
162 for (std::set<ManifestHandler*>::iterator iter = handlers.begin();
163 iter != handlers.end(); ++iter) {
164 if (!(*iter)->Validate(extension, error, warnings))
165 return false;
166 }
167 return true;
168 }
169
CreatePermission(const std::string & name)170 ManifestPermission* ManifestHandlerRegistry::CreatePermission(
171 const std::string& name) {
172 ManifestHandlerMap::const_iterator it = handlers_.find(name);
173 if (it == handlers_.end())
174 return NULL;
175
176 return it->second->CreatePermission();
177 }
178
AddExtensionInitialRequiredPermissions(const Extension * extension,ManifestPermissionSet * permission_set)179 void ManifestHandlerRegistry::AddExtensionInitialRequiredPermissions(
180 const Extension* extension, ManifestPermissionSet* permission_set) {
181 for (ManifestHandlerMap::const_iterator it = handlers_.begin();
182 it != handlers_.end(); ++it) {
183 ManifestPermission* permission =
184 it->second->CreateInitialRequiredPermission(extension);
185 if (permission) {
186 permission_set->insert(permission);
187 }
188 }
189 }
190
191 // static
SetForTesting(ManifestHandlerRegistry * new_registry)192 ManifestHandlerRegistry* ManifestHandlerRegistry::SetForTesting(
193 ManifestHandlerRegistry* new_registry) {
194 ManifestHandlerRegistry* old_registry = GetRegistry();
195 if (new_registry != g_registry.Pointer())
196 g_registry_override = new_registry;
197 else
198 g_registry_override = NULL;
199 return old_registry;
200 }
201
SortManifestHandlers()202 void ManifestHandlerRegistry::SortManifestHandlers() {
203 std::set<ManifestHandler*> unsorted_handlers;
204 for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
205 iter != handlers_.end(); ++iter) {
206 unsorted_handlers.insert(iter->second.get());
207 }
208
209 int priority = 0;
210 while (true) {
211 std::set<ManifestHandler*> next_unsorted_handlers;
212 for (std::set<ManifestHandler*>::const_iterator iter =
213 unsorted_handlers.begin();
214 iter != unsorted_handlers.end(); ++iter) {
215 ManifestHandler* handler = *iter;
216 const std::vector<std::string>& prerequisites =
217 handler->PrerequisiteKeys();
218 int unsatisfied = prerequisites.size();
219 for (size_t i = 0; i < prerequisites.size(); ++i) {
220 ManifestHandlerMap::const_iterator prereq_iter =
221 handlers_.find(prerequisites[i]);
222 // If the prerequisite does not exist, crash.
223 CHECK(prereq_iter != handlers_.end())
224 << "Extension manifest handler depends on unrecognized key "
225 << prerequisites[i];
226 // Prerequisite is in our map.
227 if (ContainsKey(priority_map_, prereq_iter->second.get()))
228 unsatisfied--;
229 }
230 if (unsatisfied == 0) {
231 priority_map_[handler] = priority;
232 priority++;
233 } else {
234 // Put in the list for next time.
235 next_unsorted_handlers.insert(handler);
236 }
237 }
238 if (next_unsorted_handlers.size() == unsorted_handlers.size())
239 break;
240 unsorted_handlers.swap(next_unsorted_handlers);
241 }
242
243 // If there are any leftover unsorted handlers, they must have had
244 // circular dependencies.
245 CHECK(unsorted_handlers.size() == 0) << "Extension manifest handlers have "
246 << "circular dependencies!";
247 }
248
249 } // namespace extensions
250