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