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