Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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/extension_messages.h"
      6 
      7 #include "chrome/common/extensions/extension_constants.h"
      8 #include "content/public/common/common_param_traits.h"
      9 #include "extensions/common/extension.h"
     10 #include "extensions/common/manifest.h"
     11 #include "extensions/common/manifest_handler.h"
     12 #include "extensions/common/permissions/permissions_data.h"
     13 #include "extensions/common/permissions/permissions_info.h"
     14 
     15 using extensions::APIPermission;
     16 using extensions::APIPermissionInfo;
     17 using extensions::APIPermissionSet;
     18 using extensions::Extension;
     19 using extensions::Manifest;
     20 using extensions::ManifestHandler;
     21 using extensions::ManifestPermission;
     22 using extensions::ManifestPermissionSet;
     23 using extensions::PermissionSet;
     24 using extensions::URLPatternSet;
     25 
     26 ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params()
     27     : location(Manifest::INVALID_LOCATION),
     28       creation_flags(Extension::NO_FLAGS){}
     29 
     30 ExtensionMsg_Loaded_Params::~ExtensionMsg_Loaded_Params() {}
     31 
     32 ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params(
     33     const Extension* extension)
     34     : manifest(extension->manifest()->value()->DeepCopy()),
     35       location(extension->location()),
     36       path(extension->path()),
     37       apis(extension->GetActivePermissions()->apis()),
     38       manifest_permissions(
     39           extension->GetActivePermissions()->manifest_permissions()),
     40       explicit_hosts(extension->GetActivePermissions()->explicit_hosts()),
     41       scriptable_hosts(extension->GetActivePermissions()->scriptable_hosts()),
     42       id(extension->id()),
     43       creation_flags(extension->creation_flags()) {
     44 }
     45 
     46 scoped_refptr<Extension> ExtensionMsg_Loaded_Params::ConvertToExtension(
     47     std::string* error) const {
     48   scoped_refptr<Extension> extension =
     49       Extension::Create(path, location, *manifest, creation_flags, error);
     50   if (extension.get()) {
     51     extensions::PermissionsData::SetActivePermissions(
     52         extension.get(),
     53         new PermissionSet(apis, manifest_permissions,
     54                           explicit_hosts, scriptable_hosts));
     55   }
     56   return extension;
     57 }
     58 
     59 namespace IPC {
     60 
     61 template <>
     62 struct ParamTraits<Manifest::Location> {
     63   typedef Manifest::Location param_type;
     64   static void Write(Message* m, const param_type& p) {
     65     int val = static_cast<int>(p);
     66     WriteParam(m, val);
     67   }
     68   static bool Read(const Message* m, PickleIterator* iter, param_type* p) {
     69     int val = 0;
     70     if (!ReadParam(m, iter, &val) ||
     71         val < Manifest::INVALID_LOCATION ||
     72         val >= Manifest::NUM_LOCATIONS)
     73       return false;
     74     *p = static_cast<param_type>(val);
     75     return true;
     76   }
     77   static void Log(const param_type& p, std::string* l) {
     78     ParamTraits<int>::Log(static_cast<int>(p), l);
     79   }
     80 };
     81 
     82 void ParamTraits<URLPattern>::Write(Message* m, const param_type& p) {
     83   WriteParam(m, p.valid_schemes());
     84   WriteParam(m, p.GetAsString());
     85 }
     86 
     87 bool ParamTraits<URLPattern>::Read(const Message* m, PickleIterator* iter,
     88                                    param_type* p) {
     89   int valid_schemes;
     90   std::string spec;
     91   if (!ReadParam(m, iter, &valid_schemes) ||
     92       !ReadParam(m, iter, &spec))
     93     return false;
     94 
     95   // TODO(jstritar): We don't want the URLPattern to fail parsing when the
     96   // scheme is invalid. Instead, the pattern should parse but it should not
     97   // match the invalid patterns. We get around this by setting the valid
     98   // schemes after parsing the pattern. Update these method calls once we can
     99   // ignore scheme validation with URLPattern parse options. crbug.com/90544
    100   p->SetValidSchemes(URLPattern::SCHEME_ALL);
    101   URLPattern::ParseResult result = p->Parse(spec);
    102   p->SetValidSchemes(valid_schemes);
    103   return URLPattern::PARSE_SUCCESS == result;
    104 }
    105 
    106 void ParamTraits<URLPattern>::Log(const param_type& p, std::string* l) {
    107   LogParam(p.GetAsString(), l);
    108 }
    109 
    110 void ParamTraits<URLPatternSet>::Write(Message* m, const param_type& p) {
    111   WriteParam(m, p.patterns());
    112 }
    113 
    114 bool ParamTraits<URLPatternSet>::Read(const Message* m, PickleIterator* iter,
    115                                         param_type* p) {
    116   std::set<URLPattern> patterns;
    117   if (!ReadParam(m, iter, &patterns))
    118     return false;
    119 
    120   for (std::set<URLPattern>::iterator i = patterns.begin();
    121        i != patterns.end(); ++i)
    122     p->AddPattern(*i);
    123   return true;
    124 }
    125 
    126 void ParamTraits<URLPatternSet>::Log(const param_type& p, std::string* l) {
    127   LogParam(p.patterns(), l);
    128 }
    129 
    130 void ParamTraits<APIPermission::ID>::Write(
    131     Message* m, const param_type& p) {
    132   WriteParam(m, static_cast<int>(p));
    133 }
    134 
    135 bool ParamTraits<APIPermission::ID>::Read(
    136     const Message* m, PickleIterator* iter, param_type* p) {
    137   int api_id = -2;
    138   if (!ReadParam(m, iter, &api_id))
    139     return false;
    140 
    141   *p = static_cast<APIPermission::ID>(api_id);
    142   return true;
    143 }
    144 
    145 void ParamTraits<APIPermission::ID>::Log(
    146     const param_type& p, std::string* l) {
    147   LogParam(static_cast<int>(p), l);
    148 }
    149 
    150 void ParamTraits<APIPermission*>::Log(
    151     const param_type& p, std::string* l) {
    152   p->Log(l);
    153 }
    154 
    155 void ParamTraits<APIPermissionSet>::Write(
    156     Message* m, const param_type& p) {
    157   APIPermissionSet::const_iterator it = p.begin();
    158   const APIPermissionSet::const_iterator end = p.end();
    159   WriteParam(m, p.size());
    160   for (; it != end; ++it) {
    161     WriteParam(m, it->id());
    162     it->Write(m);
    163   }
    164 }
    165 
    166 bool ParamTraits<APIPermissionSet>::Read(
    167     const Message* m, PickleIterator* iter, param_type* r) {
    168   size_t size;
    169   if (!ReadParam(m, iter, &size))
    170     return false;
    171   for (size_t i = 0; i < size; ++i) {
    172     APIPermission::ID id;
    173     if (!ReadParam(m, iter, &id))
    174       return false;
    175     const APIPermissionInfo* permission_info =
    176       extensions::PermissionsInfo::GetInstance()->GetByID(id);
    177     if (!permission_info)
    178       return false;
    179     scoped_ptr<APIPermission> p(permission_info->CreateAPIPermission());
    180     if (!p->Read(m, iter))
    181       return false;
    182     r->insert(p.release());
    183   }
    184   return true;
    185 }
    186 
    187 void ParamTraits<APIPermissionSet>::Log(
    188     const param_type& p, std::string* l) {
    189   LogParam(p.map(), l);
    190 }
    191 
    192 void ParamTraits<ManifestPermissionSet>::Write(
    193     Message* m, const param_type& p) {
    194   ManifestPermissionSet::const_iterator it = p.begin();
    195   const ManifestPermissionSet::const_iterator end = p.end();
    196   WriteParam(m, p.size());
    197   for (; it != end; ++it) {
    198     WriteParam(m, it->name());
    199     it->Write(m);
    200   }
    201 }
    202 
    203 bool ParamTraits<ManifestPermissionSet>::Read(
    204     const Message* m, PickleIterator* iter, param_type* r) {
    205   size_t size;
    206   if (!ReadParam(m, iter, &size))
    207     return false;
    208   for (size_t i = 0; i < size; ++i) {
    209     std::string name;
    210     if (!ReadParam(m, iter, &name))
    211       return false;
    212     scoped_ptr<ManifestPermission> p(ManifestHandler::CreatePermission(name));
    213     if (!p)
    214       return false;
    215     if (!p->Read(m, iter))
    216       return false;
    217     r->insert(p.release());
    218   }
    219   return true;
    220 }
    221 
    222 void ParamTraits<ManifestPermissionSet>::Log(
    223     const param_type& p, std::string* l) {
    224   LogParam(p.map(), l);
    225 }
    226 
    227 void ParamTraits<ExtensionMsg_Loaded_Params>::Write(Message* m,
    228                                                     const param_type& p) {
    229   WriteParam(m, p.location);
    230   WriteParam(m, p.path);
    231   WriteParam(m, *(p.manifest));
    232   WriteParam(m, p.creation_flags);
    233   WriteParam(m, p.apis);
    234   WriteParam(m, p.explicit_hosts);
    235   WriteParam(m, p.scriptable_hosts);
    236 }
    237 
    238 bool ParamTraits<ExtensionMsg_Loaded_Params>::Read(const Message* m,
    239                                                    PickleIterator* iter,
    240                                                    param_type* p) {
    241   p->manifest.reset(new base::DictionaryValue());
    242   return ReadParam(m, iter, &p->location) &&
    243          ReadParam(m, iter, &p->path) &&
    244          ReadParam(m, iter, p->manifest.get()) &&
    245          ReadParam(m, iter, &p->creation_flags) &&
    246          ReadParam(m, iter, &p->apis) &&
    247          ReadParam(m, iter, &p->explicit_hosts) &&
    248          ReadParam(m, iter, &p->scriptable_hosts);
    249 }
    250 
    251 void ParamTraits<ExtensionMsg_Loaded_Params>::Log(const param_type& p,
    252                                                   std::string* l) {
    253   l->append(p.id);
    254 }
    255 
    256 }  // namespace IPC
    257