Home | History | Annotate | Download | only in common
      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 
     23 ManifestHandlerRegistry* GetRegistry() {
     24   if (!g_registry_override)
     25     return g_registry.Pointer();
     26   return g_registry_override;
     27 }
     28 
     29 }  // namespace
     30 
     31 ManifestHandler::ManifestHandler() {
     32 }
     33 
     34 ManifestHandler::~ManifestHandler() {
     35 }
     36 
     37 bool ManifestHandler::Validate(const Extension* extension,
     38                                std::string* error,
     39                                std::vector<InstallWarning>* warnings) const {
     40   return true;
     41 }
     42 
     43 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
     44   return false;
     45 }
     46 
     47 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
     48   return false;
     49 }
     50 
     51 const std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
     52   return std::vector<std::string>();
     53 }
     54 
     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 
     62 ManifestPermission* ManifestHandler::CreatePermission() {
     63   return NULL;
     64 }
     65 
     66 ManifestPermission* ManifestHandler::CreateInitialRequiredPermission(
     67     const Extension* extension) {
     68   return NULL;
     69 }
     70 
     71 // static
     72 void ManifestHandler::FinalizeRegistration() {
     73   GetRegistry()->Finalize();
     74 }
     75 
     76 // static
     77 bool ManifestHandler::IsRegistrationFinalized() {
     78   return GetRegistry()->is_finalized_;
     79 }
     80 
     81 // static
     82 bool ManifestHandler::ParseExtension(Extension* extension,
     83                                      base::string16* error) {
     84   return GetRegistry()->ParseExtension(extension, error);
     85 }
     86 
     87 // static
     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
     95 ManifestPermission* ManifestHandler::CreatePermission(const std::string& name) {
     96   return GetRegistry()->CreatePermission(name);
     97 }
     98 
     99 // static
    100 void ManifestHandler::AddExtensionInitialRequiredPermissions(
    101     const Extension* extension, ManifestPermissionSet* permission_set) {
    102   return GetRegistry()->AddExtensionInitialRequiredPermissions(extension,
    103                                                                permission_set);
    104 }
    105 
    106 // static
    107 const std::vector<std::string> ManifestHandler::SingleKey(
    108     const std::string& key) {
    109   return std::vector<std::string>(1, key);
    110 }
    111 
    112 ManifestHandlerRegistry::ManifestHandlerRegistry() : is_finalized_(false) {
    113 }
    114 
    115 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
    116 }
    117 
    118 void ManifestHandlerRegistry::Finalize() {
    119   CHECK(!is_finalized_);
    120   SortManifestHandlers();
    121   is_finalized_ = true;
    122 }
    123 
    124 void ManifestHandlerRegistry::RegisterManifestHandler(
    125     const std::string& key, linked_ptr<ManifestHandler> handler) {
    126   CHECK(!is_finalized_);
    127   handlers_[key] = handler;
    128 }
    129 
    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 
    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 
    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 
    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
    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 
    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