Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/common/permissions/api_permission_set.h" | 5 #include "extensions/common/permissions/api_permission_set.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 return false; | 102 return false; |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 | 105 |
| 106 return CreateAPIPermission(base_name, NULL, source, | 106 return CreateAPIPermission(base_name, NULL, source, |
| 107 api_permissions, error, NULL); | 107 api_permissions, error, NULL); |
| 108 } | 108 } |
| 109 | 109 |
| 110 } // namespace | 110 } // namespace |
| 111 | 111 |
| 112 template <typename T> | |
| 113 class SetOperations { | |
| 114 public: | |
| 115 typedef typename T::const_iterator const_iterator; | |
| 116 | |
| 117 static T& Assign(T& lhs, const T& rhs) { | |
| 118 const_iterator it = rhs.begin(); | |
| 119 const const_iterator end = rhs.end(); | |
| 120 while (it != end) { | |
| 121 lhs.insert(it->Clone()); | |
| 122 ++it; | |
| 123 } | |
| 124 return lhs; | |
| 125 } | |
| 126 | |
| 127 static bool Equal(const T& lhs, const T& rhs) { | |
| 128 const_iterator it = lhs.begin(); | |
| 129 const_iterator rhs_it = rhs.begin(); | |
| 130 const_iterator it_end = lhs.end(); | |
| 131 const_iterator rhs_it_end = rhs.end(); | |
| 132 | |
| 133 while (it != it_end && rhs_it != rhs_it_end) { | |
| 134 if (!it->Equal(*rhs_it)) | |
| 135 return false; | |
| 136 ++it; | |
| 137 ++rhs_it; | |
| 138 } | |
| 139 return it == it_end && rhs_it == rhs_it_end; | |
| 140 } | |
| 141 | |
| 142 static bool Contains(const T& lhs, const T& rhs) { | |
| 143 const_iterator it1 = lhs.begin(); | |
| 144 const_iterator it2 = rhs.begin(); | |
| 145 const_iterator end1 = lhs.end(); | |
| 146 const_iterator end2 = rhs.end(); | |
| 147 | |
| 148 while (it1 != end1 && it2 != end2) { | |
| 149 if (it1->id() > it2->id()) { | |
| 150 return false; | |
| 151 } else if (it1->id() < it2->id()) { | |
| 152 ++it1; | |
| 153 } else { | |
| 154 if (!it1->Contains(*it2)) | |
| 155 return false; | |
| 156 ++it1; | |
| 157 ++it2; | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 return it2 == end2; | |
| 162 } | |
| 163 | |
| 164 template <typename U> | |
| 165 static void Difference(const T& set1, const T& set2, T* set3) { | |
| 166 CHECK(set3); | |
| 167 set3->clear(); | |
| 168 | |
| 169 const_iterator it1 = set1.begin(); | |
| 170 const_iterator it2 = set2.begin(); | |
| 171 const const_iterator end1 = set1.end(); | |
| 172 const const_iterator end2 = set2.end(); | |
| 173 | |
| 174 while (it1 != end1 && it2 != end2) { | |
| 175 if (it1->id() < it2->id()) { | |
| 176 set3->insert(it1->Clone()); | |
| 177 ++it1; | |
| 178 } else if (it1->id() > it2->id()) { | |
| 179 ++it2; | |
| 180 } else { | |
| 181 U* p = it1->Diff(*it2); | |
| 182 if (p) | |
| 183 set3->insert(p); | |
| 184 ++it1; | |
| 185 ++it2; | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 while (it1 != end1) { | |
| 190 set3->insert(it1->Clone()); | |
| 191 ++it1; | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 template<typename U> | |
| 196 static void Intersection(const T& set1, const T& set2, T* set3) { | |
| 197 DCHECK(set3); | |
| 198 set3->clear(); | |
| 199 | |
| 200 const_iterator it1 = set1.begin(); | |
| 201 const_iterator it2 = set2.begin(); | |
| 202 const const_iterator end1 = set1.end(); | |
| 203 const const_iterator end2 = set2.end(); | |
| 204 | |
| 205 while (it1 != end1 && it2 != end2) { | |
| 206 if (it1->id() < it2->id()) { | |
| 207 ++it1; | |
| 208 } else if (it1->id() > it2->id()) { | |
| 209 ++it2; | |
| 210 } else { | |
| 211 U* p = it1->Intersect(*it2); | |
| 212 if (p) | |
| 213 set3->insert(p); | |
| 214 ++it1; | |
| 215 ++it2; | |
| 216 } | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 template<typename U> | |
| 221 static void Union(const T& set1, const T& set2, T* set3) { | |
| 222 DCHECK(set3); | |
| 223 set3->clear(); | |
| 224 | |
| 225 const_iterator it1 = set1.begin(); | |
| 226 const_iterator it2 = set2.begin(); | |
| 227 const const_iterator end1 = set1.end(); | |
| 228 const const_iterator end2 = set2.end(); | |
| 229 | |
| 230 while (true) { | |
| 231 if (it1 == end1) { | |
| 232 while (it2 != end2) { | |
| 233 set3->insert(it2->Clone()); | |
| 234 ++it2; | |
| 235 } | |
| 236 break; | |
| 237 } | |
| 238 if (it2 == end2) { | |
| 239 while (it1 != end1) { | |
| 240 set3->insert(it1->Clone()); | |
| 241 ++it1; | |
| 242 } | |
| 243 break; | |
| 244 } | |
| 245 if (it1->id() < it2->id()) { | |
| 246 set3->insert(it1->Clone()); | |
| 247 ++it1; | |
| 248 } else if (it1->id() > it2->id()) { | |
| 249 set3->insert(it2->Clone()); | |
| 250 ++it2; | |
| 251 } else { | |
| 252 set3->insert(it1->Union(*it2)); | |
| 253 ++it1; | |
| 254 ++it2; | |
| 255 } | |
| 256 } | |
| 257 } | |
| 258 }; | |
| 259 | |
| 260 | |
| 112 APIPermissionSet::APIPermissionSet() { | 261 APIPermissionSet::APIPermissionSet() { |
| 113 } | 262 } |
| 114 | 263 |
| 115 APIPermissionSet::APIPermissionSet(const APIPermissionSet& set) { | 264 APIPermissionSet::APIPermissionSet(const APIPermissionSet& set) { |
| 116 this->operator=(set); | 265 this->operator=(set); |
| 117 } | 266 } |
| 118 | 267 |
| 119 APIPermissionSet::~APIPermissionSet() { | 268 APIPermissionSet::~APIPermissionSet() { |
| 120 } | 269 } |
| 121 | 270 |
| 122 APIPermissionSet::const_iterator::const_iterator( | 271 APIPermissionSet::const_iterator::const_iterator( |
| 123 const APIPermissionMap::const_iterator& it) | 272 const APIPermissionMap::const_iterator& it) |
| 124 : it_(it) { | 273 : it_(it) { |
| 125 } | 274 } |
| 126 | 275 |
| 127 APIPermissionSet::const_iterator::const_iterator( | 276 APIPermissionSet::const_iterator::const_iterator( |
| 128 const const_iterator& ids_it) | 277 const const_iterator& ids_it) |
| 129 : it_(ids_it.it_) { | 278 : it_(ids_it.it_) { |
| 130 } | 279 } |
| 131 | 280 |
| 132 APIPermissionSet& APIPermissionSet::operator=(const APIPermissionSet& rhs) { | 281 APIPermissionSet& APIPermissionSet::operator=(const APIPermissionSet& rhs) { |
| 133 const_iterator it = rhs.begin(); | 282 return SetOperations<APIPermissionSet>::Assign(*this, rhs); |
| 134 const const_iterator end = rhs.end(); | |
| 135 while (it != end) { | |
| 136 insert(it->Clone()); | |
| 137 ++it; | |
| 138 } | |
| 139 return *this; | |
| 140 } | 283 } |
| 141 | 284 |
| 142 bool APIPermissionSet::operator==(const APIPermissionSet& rhs) const { | 285 bool APIPermissionSet::operator==(const APIPermissionSet& rhs) const { |
| 143 const_iterator it = begin(); | 286 return SetOperations<APIPermissionSet>::Equal(*this, rhs); |
| 144 const_iterator rhs_it = rhs.begin(); | |
| 145 const_iterator it_end = end(); | |
| 146 const_iterator rhs_it_end = rhs.end(); | |
| 147 | |
| 148 while (it != it_end && rhs_it != rhs_it_end) { | |
| 149 if (!it->Equal(*rhs_it)) | |
| 150 return false; | |
| 151 ++it; | |
| 152 ++rhs_it; | |
| 153 } | |
| 154 return it == it_end && rhs_it == rhs_it_end; | |
| 155 } | 287 } |
| 156 | 288 |
| 157 void APIPermissionSet::insert(APIPermission::ID id) { | 289 void APIPermissionSet::insert(APIPermission::ID id) { |
| 158 const APIPermissionInfo* permission_info = | 290 const APIPermissionInfo* permission_info = |
| 159 PermissionsInfo::GetInstance()->GetByID(id); | 291 PermissionsInfo::GetInstance()->GetByID(id); |
| 160 insert(permission_info->CreateAPIPermission()); | 292 insert(permission_info->CreateAPIPermission()); |
| 161 } | 293 } |
| 162 | 294 |
| 163 void APIPermissionSet::insert(APIPermission* permission) { | 295 void APIPermissionSet::insert(APIPermission* permission) { |
| 164 map_[permission->id()].reset(permission); | 296 map_[permission->id()].reset(permission); |
| 165 } | 297 } |
| 166 | 298 |
| 167 bool APIPermissionSet::Contains(const APIPermissionSet& rhs) const { | 299 bool APIPermissionSet::Contains(const APIPermissionSet& rhs) const { |
| 168 APIPermissionSet::const_iterator it1 = begin(); | 300 return SetOperations<APIPermissionSet>::Contains(*this, rhs); |
| 169 APIPermissionSet::const_iterator it2 = rhs.begin(); | |
| 170 APIPermissionSet::const_iterator end1 = end(); | |
| 171 APIPermissionSet::const_iterator end2 = rhs.end(); | |
| 172 | |
| 173 while (it1 != end1 && it2 != end2) { | |
| 174 if (it1->id() > it2->id()) { | |
| 175 return false; | |
| 176 } else if (it1->id() < it2->id()) { | |
| 177 ++it1; | |
| 178 } else { | |
| 179 if (!it1->Contains(*it2)) | |
| 180 return false; | |
| 181 ++it1; | |
| 182 ++it2; | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 return it2 == end2; | |
| 187 } | 301 } |
| 188 | 302 |
| 189 void APIPermissionSet::Difference( | 303 void APIPermissionSet::Difference( |
| 190 const APIPermissionSet& set1, | 304 const APIPermissionSet& set1, |
| 191 const APIPermissionSet& set2, | 305 const APIPermissionSet& set2, |
| 192 APIPermissionSet* set3) { | 306 APIPermissionSet* set3) { |
| 193 CHECK(set3); | 307 SetOperations<APIPermissionSet>::Difference<APIPermission>(set1, set2, set3); |
| 194 set3->clear(); | |
| 195 | |
| 196 APIPermissionSet::const_iterator it1 = set1.begin(); | |
| 197 APIPermissionSet::const_iterator it2 = set2.begin(); | |
| 198 const APIPermissionSet::const_iterator end1 = set1.end(); | |
| 199 const APIPermissionSet::const_iterator end2 = set2.end(); | |
| 200 | |
| 201 while (it1 != end1 && it2 != end2) { | |
| 202 if (it1->id() < it2->id()) { | |
| 203 set3->insert(it1->Clone()); | |
| 204 ++it1; | |
| 205 } else if (it1->id() > it2->id()) { | |
| 206 ++it2; | |
| 207 } else { | |
| 208 APIPermission* p = it1->Diff(*it2); | |
| 209 if (p) | |
| 210 set3->insert(p); | |
| 211 ++it1; | |
| 212 ++it2; | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 while (it1 != end1) { | |
| 217 set3->insert(it1->Clone()); | |
| 218 ++it1; | |
| 219 } | |
| 220 } | 308 } |
| 221 | 309 |
| 222 void APIPermissionSet::Intersection( | 310 void APIPermissionSet::Intersection( |
| 223 const APIPermissionSet& set1, | 311 const APIPermissionSet& set1, |
| 224 const APIPermissionSet& set2, | 312 const APIPermissionSet& set2, |
| 225 APIPermissionSet* set3) { | 313 APIPermissionSet* set3) { |
| 226 DCHECK(set3); | 314 SetOperations<APIPermissionSet>::Intersection<APIPermission>( |
| 227 set3->clear(); | 315 set1, set2, set3); |
| 228 | |
| 229 APIPermissionSet::const_iterator it1 = set1.begin(); | |
| 230 APIPermissionSet::const_iterator it2 = set2.begin(); | |
| 231 const APIPermissionSet::const_iterator end1 = set1.end(); | |
| 232 const APIPermissionSet::const_iterator end2 = set2.end(); | |
| 233 | |
| 234 while (it1 != end1 && it2 != end2) { | |
| 235 if (it1->id() < it2->id()) { | |
| 236 ++it1; | |
| 237 } else if (it1->id() > it2->id()) { | |
| 238 ++it2; | |
| 239 } else { | |
| 240 APIPermission* p = it1->Intersect(*it2); | |
| 241 if (p) | |
| 242 set3->insert(p); | |
| 243 ++it1; | |
| 244 ++it2; | |
| 245 } | |
| 246 } | |
| 247 } | 316 } |
| 248 | 317 |
| 249 void APIPermissionSet::Union( | 318 void APIPermissionSet::Union( |
| 250 const APIPermissionSet& set1, | 319 const APIPermissionSet& set1, |
| 251 const APIPermissionSet& set2, | 320 const APIPermissionSet& set2, |
| 252 APIPermissionSet* set3) { | 321 APIPermissionSet* set3) { |
| 253 DCHECK(set3); | 322 SetOperations<APIPermissionSet>::Union<APIPermission>(set1, set2, set3); |
| 254 set3->clear(); | |
| 255 | |
| 256 APIPermissionSet::const_iterator it1 = set1.begin(); | |
| 257 APIPermissionSet::const_iterator it2 = set2.begin(); | |
| 258 const APIPermissionSet::const_iterator end1 = set1.end(); | |
| 259 const APIPermissionSet::const_iterator end2 = set2.end(); | |
| 260 | |
| 261 while (true) { | |
| 262 if (it1 == end1) { | |
| 263 while (it2 != end2) { | |
| 264 set3->insert(it2->Clone()); | |
| 265 ++it2; | |
| 266 } | |
| 267 break; | |
| 268 } | |
| 269 if (it2 == end2) { | |
| 270 while (it1 != end1) { | |
| 271 set3->insert(it1->Clone()); | |
| 272 ++it1; | |
| 273 } | |
| 274 break; | |
| 275 } | |
| 276 if (it1->id() < it2->id()) { | |
| 277 set3->insert(it1->Clone()); | |
| 278 ++it1; | |
| 279 } else if (it1->id() > it2->id()) { | |
| 280 set3->insert(it2->Clone()); | |
| 281 ++it2; | |
| 282 } else { | |
| 283 set3->insert(it1->Union(*it2)); | |
| 284 ++it1; | |
| 285 ++it2; | |
| 286 } | |
| 287 } | |
| 288 } | 323 } |
| 289 | 324 |
| 290 // static | 325 // static |
| 291 bool APIPermissionSet::ParseFromJSON( | 326 bool APIPermissionSet::ParseFromJSON( |
| 292 const base::ListValue* permissions, | 327 const base::ListValue* permissions, |
| 293 APIPermissionSet::ParseSource source, | 328 APIPermissionSet::ParseSource source, |
| 294 APIPermissionSet* api_permissions, | 329 APIPermissionSet* api_permissions, |
| 295 string16* error, | 330 string16* error, |
| 296 std::vector<std::string>* unhandled_permissions) { | 331 std::vector<std::string>* unhandled_permissions) { |
| 297 for (size_t i = 0; i < permissions->GetSize(); ++i) { | 332 for (size_t i = 0; i < permissions->GetSize(); ++i) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 void APIPermissionSet::AddImpliedPermissions() { | 368 void APIPermissionSet::AddImpliedPermissions() { |
| 334 // The fileSystem.write and fileSystem.directory permissions imply | 369 // The fileSystem.write and fileSystem.directory permissions imply |
| 335 // fileSystem.writeDirectory. | 370 // fileSystem.writeDirectory. |
| 336 // TODO(sammc): Remove this. See http://crbug.com/284849. | 371 // TODO(sammc): Remove this. See http://crbug.com/284849. |
| 337 if (ContainsKey(map_, APIPermission::kFileSystemWrite) && | 372 if (ContainsKey(map_, APIPermission::kFileSystemWrite) && |
| 338 ContainsKey(map_, APIPermission::kFileSystemDirectory)) { | 373 ContainsKey(map_, APIPermission::kFileSystemDirectory)) { |
| 339 insert(APIPermission::kFileSystemWriteDirectory); | 374 insert(APIPermission::kFileSystemWriteDirectory); |
| 340 } | 375 } |
| 341 } | 376 } |
| 342 | 377 |
| 378 ManifestPermissionSet::ManifestPermissionSet() { | |
| 379 } | |
| 380 | |
| 381 ManifestPermissionSet::ManifestPermissionSet( | |
| 382 const ManifestPermissionSet& set) { | |
| 383 this->operator=(set); | |
| 384 } | |
| 385 | |
| 386 ManifestPermissionSet::~ManifestPermissionSet() { | |
| 387 } | |
| 388 | |
| 389 ManifestPermissionSet::const_iterator::const_iterator( | |
| 390 const ManifestPermissionMap::const_iterator& it) | |
| 391 : it_(it) { | |
| 392 } | |
| 393 | |
| 394 ManifestPermissionSet::const_iterator::const_iterator( | |
| 395 const const_iterator& ids_it) | |
| 396 : it_(ids_it.it_) { | |
| 397 } | |
| 398 | |
| 399 ManifestPermissionSet& ManifestPermissionSet::operator=( | |
| 400 const ManifestPermissionSet& rhs) { | |
| 401 return SetOperations<ManifestPermissionSet>::Assign(*this, rhs); | |
| 402 } | |
| 403 | |
| 404 bool ManifestPermissionSet::operator==(const ManifestPermissionSet& rhs) | |
| 405 const { | |
| 406 return SetOperations<ManifestPermissionSet>::Equal(*this, rhs); | |
| 407 } | |
| 408 | |
| 409 void ManifestPermissionSet::insert(std::string id) { | |
| 410 // TODO(rpaquay) | |
| 411 //const APIPermissionInfo* permission_info = | |
| 412 // PermissionsInfo::GetInstance()->GetByID(id); | |
| 413 //insert(permission_info->CreateAPIPermission()); | |
| 414 } | |
| 415 | |
| 416 void ManifestPermissionSet::insert(ManifestPermission* permission) { | |
| 417 // TODO(rpaquay) | |
| 418 //map_[permission->id()].reset(permission); | |
| 419 } | |
| 420 | |
| 421 bool ManifestPermissionSet::Contains(const ManifestPermissionSet& rhs) | |
| 422 const { | |
| 423 return SetOperations<ManifestPermissionSet>::Contains(*this, rhs); | |
| 424 } | |
| 425 | |
| 426 void ManifestPermissionSet::Difference( | |
| 427 const ManifestPermissionSet& set1, | |
| 428 const ManifestPermissionSet& set2, | |
| 429 ManifestPermissionSet* set3) { | |
| 430 SetOperations<ManifestPermissionSet>::Difference<ManifestPermission>( | |
| 431 set1, set2, set3); | |
| 432 } | |
| 433 | |
| 434 void ManifestPermissionSet::Intersection( | |
| 435 const ManifestPermissionSet& set1, | |
| 436 const ManifestPermissionSet& set2, | |
| 437 ManifestPermissionSet* set3) { | |
| 438 SetOperations<ManifestPermissionSet>::Intersection<ManifestPermission>( | |
| 439 set1, set2, set3); | |
| 440 } | |
| 441 | |
| 442 void ManifestPermissionSet::Union( | |
| 443 const ManifestPermissionSet& set1, | |
| 444 const ManifestPermissionSet& set2, | |
| 445 ManifestPermissionSet* set3) { | |
| 446 SetOperations<ManifestPermissionSet>::Union<ManifestPermission>( | |
| 447 set1, set2, set3); | |
| 448 } | |
| 449 | |
| 450 // static | |
| 451 bool ManifestPermissionSet::ParseFromJSON( | |
| 452 const base::ListValue* permissions, | |
| 453 ManifestPermissionSet* manifest_permissions, | |
| 454 string16* error, | |
| 455 std::vector<std::string>* unhandled_permissions) { | |
| 456 // TODO(rpaquay): Update name of local variables to reflect we are dealing | |
| 457 // with manifest_permissions entries. | |
| 458 for (size_t i = 0; i < permissions->GetSize(); ++i) { | |
| 459 std::string permission_name; | |
| 460 const base::Value* permission_value = NULL; | |
| 461 if (!permissions->GetString(i, &permission_name)) { | |
| 462 const base::DictionaryValue* dict = NULL; | |
| 463 // permission should be a string or a single key dict. | |
|
Yoyo Zhou
2013/11/06 04:02:36
Is this still true?
rpaquay
2013/11/06 16:16:16
I am not 100% sure yet, but i think it is. Either
| |
| 464 if (!permissions->GetDictionary(i, &dict) || dict->size() != 1) { | |
| 465 if (error) { | |
| 466 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 467 errors::kInvalidPermission, base::IntToString(i)); | |
| 468 return false; | |
| 469 } | |
| 470 LOG(WARNING) << "Permission is not a string or single key dict."; | |
| 471 continue; | |
| 472 } | |
| 473 base::DictionaryValue::Iterator it(*dict); | |
| 474 permission_name = it.key(); | |
| 475 permission_value = &it.value(); | |
| 476 } | |
| 477 | |
| 478 if (!CreateManifestPermission(permission_name, permission_value, | |
| 479 manifest_permissions, error, | |
| 480 unhandled_permissions)) | |
| 481 return false; | |
| 482 } | |
| 483 return true; | |
| 484 } | |
| 485 | |
| 486 // static | |
| 487 bool ManifestPermissionSet::CreateManifestPermission( | |
| 488 const std::string& permission_name, | |
| 489 const base::Value* permission_value, | |
| 490 ManifestPermissionSet* manifest_permissions, | |
| 491 string16* error, | |
| 492 std::vector<std::string>* unhandled_permissions) { | |
| 493 #if 0 | |
| 494 const ManifestPermission* permission = | |
| 495 ManifestHandler::CreateManifestPermission(permission_name, | |
| 496 permission_value); | |
| 497 const APIPermissionInfo* permission_info = | |
| 498 PermissionsInfo::GetInstance()->GetByName(permission_str); | |
| 499 if (permission_info) { | |
| 500 scoped_ptr<APIPermission> permission( | |
| 501 permission_info->CreateAPIPermission()); | |
| 502 if (source != APIPermissionSet::kAllowInternalPermissions && | |
| 503 permission_info->is_internal()) { | |
| 504 // An internal permission specified in permissions list is an error. | |
| 505 if (error) { | |
| 506 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 507 errors::kPermissionNotAllowedInManifest, permission_str); | |
| 508 } | |
| 509 return false; | |
| 510 } | |
| 511 | |
| 512 if (!permission->FromValue(permission_value)) { | |
| 513 if (error) { | |
| 514 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 515 errors::kInvalidPermission, permission_info->name()); | |
| 516 return false; | |
| 517 } | |
| 518 LOG(WARNING) << "Parse permission failed."; | |
| 519 } else { | |
| 520 api_permissions->insert(permission.release()); | |
| 521 } | |
| 522 return true; | |
| 523 } | |
| 524 | |
| 525 if (unhandled_permissions) | |
| 526 unhandled_permissions->push_back(permission_str); | |
| 527 else | |
| 528 LOG(WARNING) << "Unknown permission[" << permission_str << "]."; | |
| 529 #endif | |
| 530 return true; | |
| 531 } | |
| 532 | |
| 343 } // namespace extensions | 533 } // namespace extensions |
| OLD | NEW |