• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,base::string16 * error)82 bool ManifestHandler::ParseExtension(Extension* extension,
83                                      base::string16* error) {
84   return GetRegistry()->ParseExtension(extension, error);
85 }
86 
87 // static
ValidateExtension(const Extension * extension,std::string * error,std::vector<InstallWarning> * warnings)88 bool ManifestHandler::ValidateExtension(const Extension* extension,
89                                         std::string* error,
90                                         std::vector<InstallWarning>* warnings) {
91   return GetRegistry()->ValidateExtension(extension, error, warnings);
92 }
93 
94 // static
CreatePermission(const std::string & name)95 ManifestPermission* ManifestHandler::CreatePermission(const std::string& name) {
96   return GetRegistry()->CreatePermission(name);
97 }
98 
99 // static
AddExtensionInitialRequiredPermissions(const Extension * extension,ManifestPermissionSet * permission_set)100 void ManifestHandler::AddExtensionInitialRequiredPermissions(
101     const Extension* extension, ManifestPermissionSet* permission_set) {
102   return GetRegistry()->AddExtensionInitialRequiredPermissions(extension,
103                                                                permission_set);
104 }
105 
106 // static
SingleKey(const std::string & key)107 const std::vector<std::string> ManifestHandler::SingleKey(
108     const std::string& key) {
109   return std::vector<std::string>(1, key);
110 }
111 
ManifestHandlerRegistry()112 ManifestHandlerRegistry::ManifestHandlerRegistry() : is_finalized_(false) {
113 }
114 
~ManifestHandlerRegistry()115 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
116 }
117 
Finalize()118 void ManifestHandlerRegistry::Finalize() {
119   CHECK(!is_finalized_);
120   SortManifestHandlers();
121   is_finalized_ = true;
122 }
123 
RegisterManifestHandler(const std::string & key,linked_ptr<ManifestHandler> handler)124 void ManifestHandlerRegistry::RegisterManifestHandler(
125     const std::string& key, linked_ptr<ManifestHandler> handler) {
126   CHECK(!is_finalized_);
127   handlers_[key] = handler;
128 }
129 
ParseExtension(Extension * extension,base::string16 * error)130 bool ManifestHandlerRegistry::ParseExtension(Extension* extension,
131                                              base::string16* error) {
132   std::map<int, ManifestHandler*> handlers_by_priority;
133   for (ManifestHandlerMap::iterator iter = handlers_.begin();
134        iter != handlers_.end(); ++iter) {
135     ManifestHandler* handler = iter->second.get();
136     if (extension->manifest()->HasPath(iter->first) ||
137         handler->AlwaysParseForType(extension->GetType())) {
138       handlers_by_priority[priority_map_[handler]] = handler;
139     }
140   }
141   for (std::map<int, ManifestHandler*>::iterator iter =
142            handlers_by_priority.begin();
143        iter != handlers_by_priority.end(); ++iter) {
144     if (!(iter->second)->Parse(extension, error))
145       return false;
146   }
147   return true;
148 }
149 
ValidateExtension(const Extension * extension,std::string * error,std::vector<InstallWarning> * warnings)150 bool ManifestHandlerRegistry::ValidateExtension(
151     const Extension* extension,
152     std::string* error,
153     std::vector<InstallWarning>* warnings) {
154   std::set<ManifestHandler*> handlers;
155   for (ManifestHandlerMap::iterator iter = handlers_.begin();
156        iter != handlers_.end(); ++iter) {
157     ManifestHandler* handler = iter->second.get();
158     if (extension->manifest()->HasPath(iter->first) ||
159         handler->AlwaysValidateForType(extension->GetType())) {
160       handlers.insert(handler);
161     }
162   }
163   for (std::set<ManifestHandler*>::iterator iter = handlers.begin();
164        iter != handlers.end(); ++iter) {
165     if (!(*iter)->Validate(extension, error, warnings))
166       return false;
167   }
168   return true;
169 }
170 
CreatePermission(const std::string & name)171 ManifestPermission* ManifestHandlerRegistry::CreatePermission(
172     const std::string& name) {
173   ManifestHandlerMap::const_iterator it = handlers_.find(name);
174   if (it == handlers_.end())
175     return NULL;
176 
177   return it->second->CreatePermission();
178 }
179 
AddExtensionInitialRequiredPermissions(const Extension * extension,ManifestPermissionSet * permission_set)180 void ManifestHandlerRegistry::AddExtensionInitialRequiredPermissions(
181     const Extension* extension, ManifestPermissionSet* permission_set) {
182   for (ManifestHandlerMap::const_iterator it = handlers_.begin();
183       it != handlers_.end(); ++it) {
184     ManifestPermission* permission =
185         it->second->CreateInitialRequiredPermission(extension);
186     if (permission) {
187       permission_set->insert(permission);
188     }
189   }
190 }
191 
192 // static
SetForTesting(ManifestHandlerRegistry * new_registry)193 ManifestHandlerRegistry* ManifestHandlerRegistry::SetForTesting(
194     ManifestHandlerRegistry* new_registry) {
195   ManifestHandlerRegistry* old_registry = GetRegistry();
196   if (new_registry != g_registry.Pointer())
197     g_registry_override = new_registry;
198   else
199     g_registry_override = NULL;
200   return old_registry;
201 }
202 
SortManifestHandlers()203 void ManifestHandlerRegistry::SortManifestHandlers() {
204   std::set<ManifestHandler*> unsorted_handlers;
205   for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
206        iter != handlers_.end(); ++iter) {
207     unsorted_handlers.insert(iter->second.get());
208   }
209 
210   int priority = 0;
211   while (true) {
212     std::set<ManifestHandler*> next_unsorted_handlers;
213     for (std::set<ManifestHandler*>::const_iterator iter =
214              unsorted_handlers.begin();
215          iter != unsorted_handlers.end(); ++iter) {
216       ManifestHandler* handler = *iter;
217       const std::vector<std::string>& prerequisites =
218           handler->PrerequisiteKeys();
219       int unsatisfied = prerequisites.size();
220       for (size_t i = 0; i < prerequisites.size(); ++i) {
221         ManifestHandlerMap::const_iterator prereq_iter =
222             handlers_.find(prerequisites[i]);
223         // If the prerequisite does not exist, crash.
224         CHECK(prereq_iter != handlers_.end())
225             << "Extension manifest handler depends on unrecognized key "
226             << prerequisites[i];
227         // Prerequisite is in our map.
228         if (ContainsKey(priority_map_, prereq_iter->second.get()))
229           unsatisfied--;
230       }
231       if (unsatisfied == 0) {
232         priority_map_[handler] = priority;
233         priority++;
234       } else {
235         // Put in the list for next time.
236         next_unsorted_handlers.insert(handler);
237       }
238     }
239     if (next_unsorted_handlers.size() == unsorted_handlers.size())
240       break;
241     unsorted_handlers.swap(next_unsorted_handlers);
242   }
243 
244   // If there are any leftover unsorted handlers, they must have had
245   // circular dependencies.
246   CHECK_EQ(unsorted_handlers.size(), std::set<ManifestHandler*>::size_type(0))
247       << "Extension manifest handlers have circular dependencies!";
248 }
249 
250 }  // namespace extensions
251