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