Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/features/simple_feature.h" | 5 #include "extensions/common/features/simple_feature.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 has_parent_(false) {} | 230 has_parent_(false) {} |
| 231 | 231 |
| 232 SimpleFeature::~SimpleFeature() {} | 232 SimpleFeature::~SimpleFeature() {} |
| 233 | 233 |
| 234 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { | 234 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { |
| 235 filters_.push_back(make_linked_ptr(filter.release())); | 235 filters_.push_back(make_linked_ptr(filter.release())); |
| 236 } | 236 } |
| 237 | 237 |
| 238 std::string SimpleFeature::Parse(const base::DictionaryValue* value) { | 238 std::string SimpleFeature::Parse(const base::DictionaryValue* value) { |
| 239 ParseURLPatterns(value, "matches", &matches_); | 239 ParseURLPatterns(value, "matches", &matches_); |
| 240 ParseSet(value, "blacklist", &blacklist_); | |
| 240 ParseSet(value, "whitelist", &whitelist_); | 241 ParseSet(value, "whitelist", &whitelist_); |
| 241 ParseSet(value, "dependencies", &dependencies_); | 242 ParseSet(value, "dependencies", &dependencies_); |
| 242 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, | 243 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, |
| 243 g_mappings.Get().extension_types); | 244 g_mappings.Get().extension_types); |
| 244 ParseEnumSet<Context>(value, "contexts", &contexts_, | 245 ParseEnumSet<Context>(value, "contexts", &contexts_, |
| 245 g_mappings.Get().contexts); | 246 g_mappings.Get().contexts); |
| 246 ParseEnum<Location>(value, "location", &location_, | 247 ParseEnum<Location>(value, "location", &location_, |
| 247 g_mappings.Get().locations); | 248 g_mappings.Get().locations); |
| 248 ParseEnumSet<Platform>(value, "platforms", &platforms_, | 249 ParseEnumSet<Platform>(value, "platforms", &platforms_, |
| 249 g_mappings.Get().platforms); | 250 g_mappings.Get().platforms); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 if (!extension_types_.empty() && | 286 if (!extension_types_.empty() && |
| 286 extension_types_.find(type_to_check) == extension_types_.end()) { | 287 extension_types_.find(type_to_check) == extension_types_.end()) { |
| 287 return CreateAvailability(INVALID_TYPE, type); | 288 return CreateAvailability(INVALID_TYPE, type); |
| 288 } | 289 } |
| 289 | 290 |
| 290 // Component extensions can access any feature. | 291 // Component extensions can access any feature. |
| 291 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too? | 292 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too? |
| 292 if (location == Manifest::COMPONENT) | 293 if (location == Manifest::COMPONENT) |
| 293 return CreateAvailability(IS_AVAILABLE, type); | 294 return CreateAvailability(IS_AVAILABLE, type); |
| 294 | 295 |
| 296 if (!blacklist_.empty()) { | |
|
not at google - send to devlin
2014/05/01 20:55:06
the !blacklist_.empty() check isn't really necessa
benwells
2014/05/02 00:58:52
Done.
| |
| 297 if (IsIdInBlacklist(extension_id)) | |
| 298 return CreateAvailability(FOUND_IN_BLACKLIST, type); | |
| 299 } | |
| 300 | |
| 295 if (!whitelist_.empty()) { | 301 if (!whitelist_.empty()) { |
| 296 if (!IsIdInWhitelist(extension_id)) { | 302 if (!IsIdInWhitelist(extension_id)) { |
| 297 // TODO(aa): This is gross. There should be a better way to test the | 303 // TODO(aa): This is gross. There should be a better way to test the |
| 298 // whitelist. | 304 // whitelist. |
| 299 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 305 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 300 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) | 306 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) |
| 301 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); | 307 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); |
| 302 | 308 |
| 303 std::string whitelist_switch_value = | 309 std::string whitelist_switch_value = |
| 304 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 310 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 | 374 |
| 369 std::string SimpleFeature::GetAvailabilityMessage( | 375 std::string SimpleFeature::GetAvailabilityMessage( |
| 370 AvailabilityResult result, | 376 AvailabilityResult result, |
| 371 Manifest::Type type, | 377 Manifest::Type type, |
| 372 const GURL& url, | 378 const GURL& url, |
| 373 Context context) const { | 379 Context context) const { |
| 374 switch (result) { | 380 switch (result) { |
| 375 case IS_AVAILABLE: | 381 case IS_AVAILABLE: |
| 376 return std::string(); | 382 return std::string(); |
| 377 case NOT_FOUND_IN_WHITELIST: | 383 case NOT_FOUND_IN_WHITELIST: |
| 384 case FOUND_IN_BLACKLIST: | |
| 378 return base::StringPrintf( | 385 return base::StringPrintf( |
| 379 "'%s' is not allowed for specified extension ID.", | 386 "'%s' is not allowed for specified extension ID.", |
| 380 name().c_str()); | 387 name().c_str()); |
| 381 case INVALID_URL: | 388 case INVALID_URL: |
| 382 return base::StringPrintf("'%s' is not allowed on %s.", | 389 return base::StringPrintf("'%s' is not allowed on %s.", |
| 383 name().c_str(), url.spec().c_str()); | 390 name().c_str(), url.spec().c_str()); |
| 384 case INVALID_TYPE: | 391 case INVALID_TYPE: |
| 385 return base::StringPrintf( | 392 return base::StringPrintf( |
| 386 "'%s' is only allowed for %s, but this is a %s.", | 393 "'%s' is only allowed for %s, but this is a %s.", |
| 387 name().c_str(), | 394 name().c_str(), |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 std::set<Feature::Context>* SimpleFeature::GetContexts() { | 466 std::set<Feature::Context>* SimpleFeature::GetContexts() { |
| 460 return &contexts_; | 467 return &contexts_; |
| 461 } | 468 } |
| 462 | 469 |
| 463 bool SimpleFeature::IsInternal() const { | 470 bool SimpleFeature::IsInternal() const { |
| 464 return false; | 471 return false; |
| 465 } | 472 } |
| 466 | 473 |
| 467 bool SimpleFeature::IsBlockedInServiceWorker() const { return false; } | 474 bool SimpleFeature::IsBlockedInServiceWorker() const { return false; } |
| 468 | 475 |
| 476 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { | |
| 477 return IsIdInList(extension_id, blacklist_); | |
| 478 } | |
| 479 | |
| 469 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { | 480 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { |
| 470 return IsIdInWhitelist(extension_id, whitelist_); | 481 return IsIdInList(extension_id, whitelist_); |
| 471 } | 482 } |
| 472 | 483 |
| 473 // static | 484 // static |
| 474 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id, | 485 bool SimpleFeature::IsIdInList(const std::string& extension_id, |
| 475 const std::set<std::string>& whitelist) { | 486 const std::set<std::string>& list) { |
| 476 // Belt-and-suspenders philosophy here. We should be pretty confident by this | 487 // Belt-and-suspenders philosophy here. We should be pretty confident by this |
| 477 // point that we've validated the extension ID format, but in case something | 488 // point that we've validated the extension ID format, but in case something |
| 478 // slips through, we avoid a class of attack where creative ID manipulation | 489 // slips through, we avoid a class of attack where creative ID manipulation |
| 479 // leads to hash collisions. | 490 // leads to hash collisions. |
| 480 if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters | 491 if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters |
| 481 return false; | 492 return false; |
| 482 | 493 |
| 483 if (whitelist.find(extension_id) != whitelist.end() || | 494 if (list.find(extension_id) != list.end() || |
| 484 whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) { | 495 list.find(HashExtensionId(extension_id)) != list.end()) { |
| 485 return true; | 496 return true; |
| 486 } | 497 } |
| 487 | 498 |
| 488 return false; | 499 return false; |
| 489 } | 500 } |
| 490 | 501 |
| 491 bool SimpleFeature::MatchesManifestLocation( | 502 bool SimpleFeature::MatchesManifestLocation( |
| 492 Manifest::Location manifest_location) const { | 503 Manifest::Location manifest_location) const { |
| 493 switch (location_) { | 504 switch (location_) { |
| 494 case SimpleFeature::UNSPECIFIED_LOCATION: | 505 case SimpleFeature::UNSPECIFIED_LOCATION: |
| 495 return true; | 506 return true; |
| 496 case SimpleFeature::COMPONENT_LOCATION: | 507 case SimpleFeature::COMPONENT_LOCATION: |
| 497 // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too? | 508 // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too? |
| 498 return manifest_location == Manifest::COMPONENT; | 509 return manifest_location == Manifest::COMPONENT; |
| 499 case SimpleFeature::POLICY_LOCATION: | 510 case SimpleFeature::POLICY_LOCATION: |
| 500 return manifest_location == Manifest::EXTERNAL_POLICY || | 511 return manifest_location == Manifest::EXTERNAL_POLICY || |
| 501 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD; | 512 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD; |
| 502 } | 513 } |
| 503 NOTREACHED(); | 514 NOTREACHED(); |
| 504 return false; | 515 return false; |
| 505 } | 516 } |
| 506 | 517 |
| 507 } // namespace extensions | 518 } // namespace extensions |
| OLD | NEW |