Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: extensions/common/features/simple_feature.cc

Issue 2137463003: [Extensions] Move Feature channel code into //extensions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/sha1.h" 15 #include "base/sha1.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "components/crx_file/id_util.h" 20 #include "components/crx_file/id_util.h"
21 #include "extensions/common/extension_api.h" 21 #include "extensions/common/extension_api.h"
22 #include "extensions/common/features/feature_channel.h"
22 #include "extensions/common/features/feature_provider.h" 23 #include "extensions/common/features/feature_provider.h"
23 #include "extensions/common/features/feature_util.h" 24 #include "extensions/common/features/feature_util.h"
24 #include "extensions/common/switches.h" 25 #include "extensions/common/switches.h"
25 26
26 using crx_file::id_util::HashedIdInHex; 27 using crx_file::id_util::HashedIdInHex;
27 28
28 namespace extensions { 29 namespace extensions {
29 30
30 namespace { 31 namespace {
31 32
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 template<typename T> 75 template<typename T>
75 void ParseEnum(const std::string& string_value, 76 void ParseEnum(const std::string& string_value,
76 T* enum_value, 77 T* enum_value,
77 const std::map<std::string, T>& mapping) { 78 const std::map<std::string, T>& mapping) {
78 const auto& iter = mapping.find(string_value); 79 const auto& iter = mapping.find(string_value);
79 if (iter == mapping.end()) 80 if (iter == mapping.end())
80 CRASH_WITH_MINIDUMP("Enum value not found: " + string_value); 81 CRASH_WITH_MINIDUMP("Enum value not found: " + string_value);
81 *enum_value = iter->second; 82 *enum_value = iter->second;
82 } 83 }
83 84
84 template<typename T> 85 template <typename T>
85 void ParseEnum(const base::DictionaryValue* value, 86 void ParseEnum(const base::Value* value,
86 const std::string& property,
87 T* enum_value, 87 T* enum_value,
88 const std::map<std::string, T>& mapping) { 88 const std::map<std::string, T>& mapping) {
89 std::string string_value; 89 std::string string_value;
90 if (!value->GetString(property, &string_value)) 90 if (!value->GetAsString(&string_value))
91 return; 91 return;
92 92
93 ParseEnum(string_value, enum_value, mapping); 93 ParseEnum(string_value, enum_value, mapping);
94 } 94 }
95 95
96 template<typename T> 96 template<typename T>
97 void ParseEnumVector(const base::Value* value, 97 void ParseEnumVector(const base::Value* value,
98 std::vector<T>* enum_vector, 98 std::vector<T>* enum_vector,
99 const std::map<std::string, T>& mapping) { 99 const std::map<std::string, T>& mapping) {
100 enum_vector->clear(); 100 enum_vector->clear();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 return "hosted app"; 183 return "hosted app";
184 case Feature::WEBUI_CONTEXT: 184 case Feature::WEBUI_CONTEXT:
185 return "webui"; 185 return "webui";
186 case Feature::SERVICE_WORKER_CONTEXT: 186 case Feature::SERVICE_WORKER_CONTEXT:
187 return "service worker"; 187 return "service worker";
188 } 188 }
189 NOTREACHED(); 189 NOTREACHED();
190 return ""; 190 return "";
191 } 191 }
192 192
193 std::string GetDisplayName(version_info::Channel channel) {
194 switch (channel) {
195 case version_info::Channel::UNKNOWN:
196 return "trunk";
197 case version_info::Channel::CANARY:
198 return "canary";
199 case version_info::Channel::DEV:
200 return "dev";
201 case version_info::Channel::BETA:
202 return "beta";
203 case version_info::Channel::STABLE:
204 return "stable";
205 }
206 NOTREACHED();
207 return "";
208 }
209
193 // Gets a human-readable list of the display names (pluralized, comma separated 210 // Gets a human-readable list of the display names (pluralized, comma separated
194 // with the "and" in the correct place) for each of |enum_types|. 211 // with the "and" in the correct place) for each of |enum_types|.
195 template <typename EnumType> 212 template <typename EnumType>
196 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { 213 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) {
197 std::string display_name_list; 214 std::string display_name_list;
198 for (size_t i = 0; i < enum_types.size(); ++i) { 215 for (size_t i = 0; i < enum_types.size(); ++i) {
199 // Pluralize type name. 216 // Pluralize type name.
200 display_name_list += GetDisplayName(enum_types[i]) + "s"; 217 display_name_list += GetDisplayName(enum_types[i]) + "s";
201 // Comma-separate entries, with an Oxford comma if there is more than 2 218 // Comma-separate entries, with an Oxford comma if there is more than 2
202 // total entries. 219 // total entries.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 284
268 locations["component"] = SimpleFeature::COMPONENT_LOCATION; 285 locations["component"] = SimpleFeature::COMPONENT_LOCATION;
269 locations["external_component"] = 286 locations["external_component"] =
270 SimpleFeature::EXTERNAL_COMPONENT_LOCATION; 287 SimpleFeature::EXTERNAL_COMPONENT_LOCATION;
271 locations["policy"] = SimpleFeature::POLICY_LOCATION; 288 locations["policy"] = SimpleFeature::POLICY_LOCATION;
272 289
273 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; 290 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM;
274 platforms["linux"] = Feature::LINUX_PLATFORM; 291 platforms["linux"] = Feature::LINUX_PLATFORM;
275 platforms["mac"] = Feature::MACOSX_PLATFORM; 292 platforms["mac"] = Feature::MACOSX_PLATFORM;
276 platforms["win"] = Feature::WIN_PLATFORM; 293 platforms["win"] = Feature::WIN_PLATFORM;
294
295 channels["trunk"] = version_info::Channel::UNKNOWN;
296 channels["canary"] = version_info::Channel::CANARY;
297 channels["dev"] = version_info::Channel::DEV;
298 channels["beta"] = version_info::Channel::BETA;
299 channels["stable"] = version_info::Channel::STABLE;
277 } 300 }
278 301
279 std::map<std::string, Manifest::Type> extension_types; 302 std::map<std::string, Manifest::Type> extension_types;
303 std::map<std::string, version_info::Channel> channels;
lazyboy 2016/07/12 00:35:13 nit: any reason this is here and not after |platfo
Devlin 2016/07/12 19:10:00 Nope, moved.
280 std::map<std::string, Feature::Context> contexts; 304 std::map<std::string, Feature::Context> contexts;
281 std::map<std::string, SimpleFeature::Location> locations; 305 std::map<std::string, SimpleFeature::Location> locations;
282 std::map<std::string, Feature::Platform> platforms; 306 std::map<std::string, Feature::Platform> platforms;
283 }; 307 };
284 308
285 SimpleFeature::SimpleFeature() 309 SimpleFeature::SimpleFeature()
286 : location_(UNSPECIFIED_LOCATION), 310 : location_(UNSPECIFIED_LOCATION),
287 min_manifest_version_(0), 311 min_manifest_version_(0),
288 max_manifest_version_(0), 312 max_manifest_version_(0),
289 component_extensions_auto_granted_(true) {} 313 component_extensions_auto_granted_(true) {}
290 314
291 SimpleFeature::~SimpleFeature() {} 315 SimpleFeature::~SimpleFeature() {}
292 316
293 bool SimpleFeature::HasDependencies() const {
294 return !dependencies_.empty();
295 }
296
297 void SimpleFeature::AddFilter(std::unique_ptr<SimpleFeatureFilter> filter) {
lazyboy 2016/07/12 00:35:12 As we're not using SimpleFeatureFilter anymore, we
Devlin 2016/07/12 19:10:00 Whoops! Meant to do that, but looks like I only g
298 filters_.push_back(std::move(filter));
299 }
300
301 std::string SimpleFeature::Parse(const base::DictionaryValue* dictionary) { 317 std::string SimpleFeature::Parse(const base::DictionaryValue* dictionary) {
302 static base::LazyInstance<SimpleFeature::Mappings> mappings = 318 static base::LazyInstance<SimpleFeature::Mappings> mappings =
303 LAZY_INSTANCE_INITIALIZER; 319 LAZY_INSTANCE_INITIALIZER;
304 320
305 no_parent_ = false; 321 no_parent_ = false;
306 for (base::DictionaryValue::Iterator it(*dictionary); 322 for (base::DictionaryValue::Iterator it(*dictionary);
307 !it.IsAtEnd(); 323 !it.IsAtEnd();
308 it.Advance()) { 324 it.Advance()) {
309 std::string key = it.key(); 325 std::string key = it.key();
310 const base::Value* value = &it.value(); 326 const base::Value* value = &it.value();
311 if (key == "matches") { 327 if (key == "matches") {
312 ParseURLPatterns(dictionary, "matches", &matches_); 328 ParseURLPatterns(dictionary, "matches", &matches_);
313 } else if (key == "blacklist") { 329 } else if (key == "blacklist") {
314 ParseVector(value, &blacklist_); 330 ParseVector(value, &blacklist_);
315 } else if (key == "whitelist") { 331 } else if (key == "whitelist") {
316 ParseVector(value, &whitelist_); 332 ParseVector(value, &whitelist_);
317 } else if (key == "dependencies") { 333 } else if (key == "dependencies") {
318 ParseVector(value, &dependencies_); 334 ParseVector(value, &dependencies_);
319 } else if (key == "extension_types") { 335 } else if (key == "extension_types") {
320 ParseEnumVector<Manifest::Type>(value, &extension_types_, 336 ParseEnumVector<Manifest::Type>(value, &extension_types_,
321 mappings.Get().extension_types); 337 mappings.Get().extension_types);
322 } else if (key == "contexts") { 338 } else if (key == "contexts") {
323 ParseEnumVector<Context>(value, &contexts_, 339 ParseEnumVector<Context>(value, &contexts_,
324 mappings.Get().contexts); 340 mappings.Get().contexts);
325 } else if (key == "location") { 341 } else if (key == "location") {
326 ParseEnum<Location>(dictionary, "location", &location_, 342 ParseEnum<Location>(value, &location_, mappings.Get().locations);
327 mappings.Get().locations);
328 } else if (key == "platforms") { 343 } else if (key == "platforms") {
329 ParseEnumVector<Platform>(value, &platforms_, 344 ParseEnumVector<Platform>(value, &platforms_,
330 mappings.Get().platforms); 345 mappings.Get().platforms);
331 } else if (key == "min_manifest_version") { 346 } else if (key == "min_manifest_version") {
332 dictionary->GetInteger("min_manifest_version", &min_manifest_version_); 347 dictionary->GetInteger("min_manifest_version", &min_manifest_version_);
333 } else if (key == "max_manifest_version") { 348 } else if (key == "max_manifest_version") {
334 dictionary->GetInteger("max_manifest_version", &max_manifest_version_); 349 dictionary->GetInteger("max_manifest_version", &max_manifest_version_);
335 } else if (key == "noparent") { 350 } else if (key == "noparent") {
336 dictionary->GetBoolean("noparent", &no_parent_); 351 dictionary->GetBoolean("noparent", &no_parent_);
337 } else if (key == "component_extensions_auto_granted") { 352 } else if (key == "component_extensions_auto_granted") {
338 dictionary->GetBoolean("component_extensions_auto_granted", 353 dictionary->GetBoolean("component_extensions_auto_granted",
339 &component_extensions_auto_granted_); 354 &component_extensions_auto_granted_);
340 } else if (key == "command_line_switch") { 355 } else if (key == "command_line_switch") {
341 dictionary->GetString("command_line_switch", &command_line_switch_); 356 dictionary->GetString("command_line_switch", &command_line_switch_);
357 } else if (key == "channel") {
358 channel_.reset(new version_info::Channel(version_info::Channel::UNKNOWN));
359 ParseEnum<version_info::Channel>(value, channel_.get(),
360 mappings.Get().channels);
342 } 361 }
343 } 362 }
344 363
345 // NOTE: ideally we'd sanity check that "matches" can be specified if and 364 // NOTE: ideally we'd sanity check that "matches" can be specified if and
346 // only if there's a "web_page" or "webui" context, but without 365 // only if there's a "web_page" or "webui" context, but without
347 // (Simple)Features being aware of their own heirarchy this is impossible. 366 // (Simple)Features being aware of their own heirarchy this is impossible.
348 // 367 //
349 // For example, we might have feature "foo" available to "web_page" context 368 // For example, we might have feature "foo" available to "web_page" context
350 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override 369 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override
351 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify 370 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify
352 // "web_page" context because it's inherited, but we don't know that here. 371 // "web_page" context because it's inherited, but we don't know that here.
353 372
354 std::string result; 373 // All features must be channel-restricted, either directly or through
355 for (const auto& filter : filters_) { 374 // dependents.
356 result = filter->Parse(dictionary); 375 if (!channel_ && dependencies_.empty())
357 if (!result.empty()) 376 return name() + ": Must supply a value for channel or dependencies.";
358 break;
359 }
360 377
361 return result; 378 return std::string();
362 } 379 }
363 380
364 Feature::Availability SimpleFeature::IsAvailableToManifest( 381 Feature::Availability SimpleFeature::IsAvailableToManifest(
365 const std::string& extension_id, 382 const std::string& extension_id,
366 Manifest::Type type, 383 Manifest::Type type,
367 Manifest::Location location, 384 Manifest::Location location,
368 int manifest_version, 385 int manifest_version,
369 Platform platform) const { 386 Platform platform) const {
370 // Check extension type first to avoid granting platform app permissions 387 // Check extension type first to avoid granting platform app permissions
371 // to component extensions. 388 // to component extensions.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); 420 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type);
404 421
405 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) 422 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_)
406 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); 423 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type);
407 424
408 if (!command_line_switch_.empty() && 425 if (!command_line_switch_.empty() &&
409 !IsCommandLineSwitchEnabled(command_line_switch_)) { 426 !IsCommandLineSwitchEnabled(command_line_switch_)) {
410 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); 427 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type);
411 } 428 }
412 429
413 for (const auto& filter : filters_) { 430 if (channel_ && *channel_ < GetCurrentChannel()) {
lazyboy 2016/07/12 00:35:13 nit: drop {}
Devlin 2016/07/12 19:10:00 Done.
414 Availability availability = filter->IsAvailableToManifest( 431 return CreateAvailability(UNSUPPORTED_CHANNEL, *channel_);
415 extension_id, type, location, manifest_version, platform);
416 if (!availability.is_available())
417 return availability;
418 } 432 }
419 433
420 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, 434 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind,
421 extension_id, 435 extension_id,
422 type, 436 type,
423 location, 437 location,
424 manifest_version, 438 manifest_version,
425 platform)); 439 platform));
426 } 440 }
427 441
(...skipping 20 matching lines...) Expand all
448 return CreateAvailability(INVALID_CONTEXT, context); 462 return CreateAvailability(INVALID_CONTEXT, context);
449 463
450 // TODO(kalman): Consider checking |matches_| regardless of context type. 464 // TODO(kalman): Consider checking |matches_| regardless of context type.
451 // Fewer surprises, and if the feature configuration wants to isolate 465 // Fewer surprises, and if the feature configuration wants to isolate
452 // "matches" from say "blessed_extension" then they can use complex features. 466 // "matches" from say "blessed_extension" then they can use complex features.
453 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && 467 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) &&
454 !matches_.MatchesURL(url)) { 468 !matches_.MatchesURL(url)) {
455 return CreateAvailability(INVALID_URL, url); 469 return CreateAvailability(INVALID_URL, url);
456 } 470 }
457 471
458 for (const auto& filter : filters_) {
459 Availability availability =
460 filter->IsAvailableToContext(extension, context, url, platform);
461 if (!availability.is_available())
462 return availability;
463 }
464
465 // TODO(kalman): Assert that if the context was a webpage or WebUI context 472 // TODO(kalman): Assert that if the context was a webpage or WebUI context
466 // then at some point a "matches" restriction was checked. 473 // then at some point a "matches" restriction was checked.
467 return CheckDependencies(base::Bind( 474 return CheckDependencies(base::Bind(
468 &IsAvailableToContextForBind, extension, context, url, platform)); 475 &IsAvailableToContextForBind, extension, context, url, platform));
469 } 476 }
470 477
471 std::string SimpleFeature::GetAvailabilityMessage( 478 std::string SimpleFeature::GetAvailabilityMessage(
472 AvailabilityResult result, 479 AvailabilityResult result,
473 Manifest::Type type, 480 Manifest::Type type,
474 const GURL& url, 481 const GURL& url,
475 Context context) const { 482 Context context,
483 version_info::Channel channel) const {
476 switch (result) { 484 switch (result) {
477 case IS_AVAILABLE: 485 case IS_AVAILABLE:
478 return std::string(); 486 return std::string();
479 case NOT_FOUND_IN_WHITELIST: 487 case NOT_FOUND_IN_WHITELIST:
480 case FOUND_IN_BLACKLIST: 488 case FOUND_IN_BLACKLIST:
481 return base::StringPrintf( 489 return base::StringPrintf(
482 "'%s' is not allowed for specified extension ID.", 490 "'%s' is not allowed for specified extension ID.",
483 name().c_str()); 491 name().c_str());
484 case INVALID_URL: 492 case INVALID_URL:
485 return base::StringPrintf("'%s' is not allowed on %s.", 493 return base::StringPrintf("'%s' is not allowed on %s.",
(...skipping 29 matching lines...) Expand all
515 return base::StringPrintf( 523 return base::StringPrintf(
516 "'%s' requires manifest version of %d or lower.", 524 "'%s' requires manifest version of %d or lower.",
517 name().c_str(), 525 name().c_str(),
518 max_manifest_version_); 526 max_manifest_version_);
519 case NOT_PRESENT: 527 case NOT_PRESENT:
520 return base::StringPrintf( 528 return base::StringPrintf(
521 "'%s' requires a different Feature that is not present.", 529 "'%s' requires a different Feature that is not present.",
522 name().c_str()); 530 name().c_str());
523 case UNSUPPORTED_CHANNEL: 531 case UNSUPPORTED_CHANNEL:
524 return base::StringPrintf( 532 return base::StringPrintf(
525 "'%s' is unsupported in this version of the platform.", 533 "'%s' requires %s channel or newer, but this is the %s channel.",
526 name().c_str()); 534 name().c_str(), GetDisplayName(channel).c_str(),
535 GetDisplayName(GetCurrentChannel()).c_str());
527 case MISSING_COMMAND_LINE_SWITCH: 536 case MISSING_COMMAND_LINE_SWITCH:
528 return base::StringPrintf( 537 return base::StringPrintf(
529 "'%s' requires the '%s' command line switch to be enabled.", 538 "'%s' requires the '%s' command line switch to be enabled.",
530 name().c_str(), command_line_switch_.c_str()); 539 name().c_str(), command_line_switch_.c_str());
531 } 540 }
532 541
533 NOTREACHED(); 542 NOTREACHED();
534 return std::string(); 543 return std::string();
535 } 544 }
536 545
537 Feature::Availability SimpleFeature::CreateAvailability( 546 Feature::Availability SimpleFeature::CreateAvailability(
538 AvailabilityResult result) const { 547 AvailabilityResult result) const {
539 return Availability( 548 return Availability(
540 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), 549 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(),
541 UNSPECIFIED_CONTEXT)); 550 UNSPECIFIED_CONTEXT,
551 version_info::Channel::UNKNOWN));
542 } 552 }
543 553
544 Feature::Availability SimpleFeature::CreateAvailability( 554 Feature::Availability SimpleFeature::CreateAvailability(
545 AvailabilityResult result, Manifest::Type type) const { 555 AvailabilityResult result, Manifest::Type type) const {
546 return Availability(result, GetAvailabilityMessage(result, type, GURL(), 556 return Availability(
547 UNSPECIFIED_CONTEXT)); 557 result, GetAvailabilityMessage(result, type, GURL(), UNSPECIFIED_CONTEXT,
558 version_info::Channel::UNKNOWN));
548 } 559 }
549 560
550 Feature::Availability SimpleFeature::CreateAvailability( 561 Feature::Availability SimpleFeature::CreateAvailability(
551 AvailabilityResult result, 562 AvailabilityResult result,
552 const GURL& url) const { 563 const GURL& url) const {
553 return Availability( 564 return Availability(
554 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, 565 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url,
555 UNSPECIFIED_CONTEXT)); 566 UNSPECIFIED_CONTEXT,
567 version_info::Channel::UNKNOWN));
556 } 568 }
557 569
558 Feature::Availability SimpleFeature::CreateAvailability( 570 Feature::Availability SimpleFeature::CreateAvailability(
559 AvailabilityResult result, 571 AvailabilityResult result,
560 Context context) const { 572 Context context) const {
561 return Availability( 573 return Availability(
562 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), 574 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(),
563 context)); 575 context, version_info::Channel::UNKNOWN));
576 }
577
578 Feature::Availability SimpleFeature::CreateAvailability(
579 AvailabilityResult result,
580 version_info::Channel channel) const {
581 return Availability(
582 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(),
583 UNSPECIFIED_CONTEXT, channel));
564 } 584 }
565 585
566 bool SimpleFeature::IsInternal() const { 586 bool SimpleFeature::IsInternal() const {
567 return false; 587 return false;
568 } 588 }
569 589
570 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { 590 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const {
571 return IsIdInList(extension_id, blacklist_); 591 return IsIdInList(extension_id, blacklist_);
572 } 592 }
573 593
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { 654 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) {
635 // Belt-and-suspenders philosophy here. We should be pretty confident by this 655 // Belt-and-suspenders philosophy here. We should be pretty confident by this
636 // point that we've validated the extension ID format, but in case something 656 // point that we've validated the extension ID format, but in case something
637 // slips through, we avoid a class of attack where creative ID manipulation 657 // slips through, we avoid a class of attack where creative ID manipulation
638 // leads to hash collisions. 658 // leads to hash collisions.
639 // 128 bits / 4 = 32 mpdecimal characters 659 // 128 bits / 4 = 32 mpdecimal characters
640 return (extension_id.length() == 32); 660 return (extension_id.length() == 32);
641 } 661 }
642 662
643 } // namespace extensions 663 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698