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

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

Issue 1010973013: Refactor Uses of std::set to std::vector in SimpleFeature (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove Unsigned From Checks with STLCount Created 5 years, 8 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 <map> 8 #include <map>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/command_line.h" 12 #include "base/command_line.h"
12 #include "base/debug/alias.h" 13 #include "base/debug/alias.h"
13 #include "base/lazy_instance.h"
14 #include "base/sha1.h" 14 #include "base/sha1.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "extensions/common/extension_api.h" 19 #include "extensions/common/extension_api.h"
20 #include "extensions/common/features/feature_provider.h" 20 #include "extensions/common/features/feature_provider.h"
21 #include "extensions/common/switches.h" 21 #include "extensions/common/switches.h"
22 22
23 namespace extensions { 23 namespace extensions {
(...skipping 12 matching lines...) Expand all
36 } 36 }
37 37
38 Feature::Availability IsAvailableToContextForBind(const Extension* extension, 38 Feature::Availability IsAvailableToContextForBind(const Extension* extension,
39 Feature::Context context, 39 Feature::Context context,
40 const GURL& url, 40 const GURL& url,
41 Feature::Platform platform, 41 Feature::Platform platform,
42 const Feature* feature) { 42 const Feature* feature) {
43 return feature->IsAvailableToContext(extension, context, url, platform); 43 return feature->IsAvailableToContext(extension, context, url, platform);
44 } 44 }
45 45
46 struct Mappings {
47 Mappings() {
48 extension_types["extension"] = Manifest::TYPE_EXTENSION;
49 extension_types["theme"] = Manifest::TYPE_THEME;
50 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP;
51 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP;
52 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP;
53 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE;
54
55 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT;
56 contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT;
57 contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT;
58 contexts["web_page"] = Feature::WEB_PAGE_CONTEXT;
59 contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT;
60 contexts["webui"] = Feature::WEBUI_CONTEXT;
61
62 locations["component"] = SimpleFeature::COMPONENT_LOCATION;
63 locations["external_component"] =
64 SimpleFeature::EXTERNAL_COMPONENT_LOCATION;
65 locations["policy"] = SimpleFeature::POLICY_LOCATION;
66
67 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM;
68 platforms["linux"] = Feature::LINUX_PLATFORM;
69 platforms["mac"] = Feature::MACOSX_PLATFORM;
70 platforms["win"] = Feature::WIN_PLATFORM;
71 }
72
73 std::map<std::string, Manifest::Type> extension_types;
74 std::map<std::string, Feature::Context> contexts;
75 std::map<std::string, SimpleFeature::Location> locations;
76 std::map<std::string, Feature::Platform> platforms;
77 };
78
79 base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER;
80
81 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff? 46 // TODO(aa): Can we replace all this manual parsing with JSON schema stuff?
82 47
83 void ParseSet(const base::DictionaryValue* value, 48 void ParseVector(const base::Value* value,
84 const std::string& property, 49 std::vector<std::string>* vector) {
85 std::set<std::string>* set) {
86 const base::ListValue* list_value = NULL; 50 const base::ListValue* list_value = NULL;
87 if (!value->GetList(property, &list_value)) 51 if (!value->GetAsList(&list_value))
88 return; 52 return;
89 53
90 set->clear(); 54 vector->clear();
91 for (size_t i = 0; i < list_value->GetSize(); ++i) { 55 size_t list_size = list_value->GetSize();
56 vector->reserve(list_size);
57 for (size_t i = 0; i < list_size; ++i) {
92 std::string str_val; 58 std::string str_val;
93 CHECK(list_value->GetString(i, &str_val)) << property << " " << i; 59 CHECK(list_value->GetString(i, &str_val));
94 set->insert(str_val); 60 vector->push_back(str_val);
95 } 61 }
62 std::sort(vector->begin(), vector->end());
96 } 63 }
97 64
98 template<typename T> 65 template<typename T>
99 void ParseEnum(const std::string& string_value, 66 void ParseEnum(const std::string& string_value,
100 T* enum_value, 67 T* enum_value,
101 const std::map<std::string, T>& mapping) { 68 const std::map<std::string, T>& mapping) {
102 const auto& iter = mapping.find(string_value); 69 const auto& iter = mapping.find(string_value);
103 if (iter == mapping.end()) { 70 if (iter == mapping.end()) {
104 // For http://crbug.com/365192. 71 // For http://crbug.com/365192.
105 char minidump[256]; 72 char minidump[256];
(...skipping 11 matching lines...) Expand all
117 T* enum_value, 84 T* enum_value,
118 const std::map<std::string, T>& mapping) { 85 const std::map<std::string, T>& mapping) {
119 std::string string_value; 86 std::string string_value;
120 if (!value->GetString(property, &string_value)) 87 if (!value->GetString(property, &string_value))
121 return; 88 return;
122 89
123 ParseEnum(string_value, enum_value, mapping); 90 ParseEnum(string_value, enum_value, mapping);
124 } 91 }
125 92
126 template<typename T> 93 template<typename T>
127 void ParseEnumSet(const base::DictionaryValue* value, 94 void ParseEnumVector(const base::Value* value,
128 const std::string& property, 95 std::vector<T>* enum_vector,
129 std::set<T>* enum_set, 96 const std::map<std::string, T>& mapping) {
130 const std::map<std::string, T>& mapping) { 97 enum_vector->clear();
131 if (!value->HasKey(property))
132 return;
133
134 enum_set->clear();
135
136 std::string property_string; 98 std::string property_string;
137 if (value->GetString(property, &property_string)) { 99 if (value->GetAsString(&property_string)) {
138 if (property_string == "all") { 100 if (property_string == "all") {
101 enum_vector->reserve(mapping.size());
139 for (const auto& it : mapping) 102 for (const auto& it : mapping)
140 enum_set->insert(it.second); 103 enum_vector->push_back(it.second);
141 } 104 }
105 std::sort(enum_vector->begin(), enum_vector->end());
142 return; 106 return;
143 } 107 }
144 108
145 std::set<std::string> string_set; 109 std::vector<std::string> string_vector;
146 ParseSet(value, property, &string_set); 110 ParseVector(value, &string_vector);
147 for (const auto& str : string_set) { 111 enum_vector->reserve(string_vector.size());
112 for (const auto& str : string_vector) {
148 T enum_value = static_cast<T>(0); 113 T enum_value = static_cast<T>(0);
149 ParseEnum(str, &enum_value, mapping); 114 ParseEnum(str, &enum_value, mapping);
150 enum_set->insert(enum_value); 115 enum_vector->push_back(enum_value);
151 } 116 }
117 std::sort(enum_vector->begin(), enum_vector->end());
152 } 118 }
153 119
154 void ParseURLPatterns(const base::DictionaryValue* value, 120 void ParseURLPatterns(const base::DictionaryValue* value,
155 const std::string& key, 121 const std::string& key,
156 URLPatternSet* set) { 122 URLPatternSet* set) {
157 const base::ListValue* matches = NULL; 123 const base::ListValue* matches = NULL;
158 if (value->GetList(key, &matches)) { 124 if (value->GetList(key, &matches)) {
159 set->ClearPatterns(); 125 set->ClearPatterns();
160 for (size_t i = 0; i < matches->GetSize(); ++i) { 126 for (size_t i = 0; i < matches->GetSize(); ++i) {
161 std::string pattern; 127 std::string pattern;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 217 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
252 if (command_line->HasSwitch(switch_name + "=1")) 218 if (command_line->HasSwitch(switch_name + "=1"))
253 return true; 219 return true;
254 if (command_line->HasSwitch(std::string("enable-") + switch_name)) 220 if (command_line->HasSwitch(std::string("enable-") + switch_name))
255 return true; 221 return true;
256 return false; 222 return false;
257 } 223 }
258 224
259 } // namespace 225 } // namespace
260 226
227 struct SimpleFeature::Mappings {
228 Mappings() {
229 extension_types["extension"] = Manifest::TYPE_EXTENSION;
230 extension_types["theme"] = Manifest::TYPE_THEME;
231 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP;
232 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP;
233 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP;
234 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE;
235
236 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT;
237 contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT;
238 contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT;
239 contexts["web_page"] = Feature::WEB_PAGE_CONTEXT;
240 contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT;
241 contexts["webui"] = Feature::WEBUI_CONTEXT;
242
243 locations["component"] = SimpleFeature::COMPONENT_LOCATION;
244 locations["external_component"] =
245 SimpleFeature::EXTERNAL_COMPONENT_LOCATION;
246 locations["policy"] = SimpleFeature::POLICY_LOCATION;
247
248 platforms["chromeos"] = Feature::CHROMEOS_PLATFORM;
249 platforms["linux"] = Feature::LINUX_PLATFORM;
250 platforms["mac"] = Feature::MACOSX_PLATFORM;
251 platforms["win"] = Feature::WIN_PLATFORM;
252 }
253
254 std::map<std::string, Manifest::Type> extension_types;
255 std::map<std::string, Feature::Context> contexts;
256 std::map<std::string, SimpleFeature::Location> locations;
257 std::map<std::string, Feature::Platform> platforms;
258 };
259
261 SimpleFeature::SimpleFeature() 260 SimpleFeature::SimpleFeature()
262 : location_(UNSPECIFIED_LOCATION), 261 : location_(UNSPECIFIED_LOCATION),
263 min_manifest_version_(0), 262 min_manifest_version_(0),
264 max_manifest_version_(0), 263 max_manifest_version_(0),
265 component_extensions_auto_granted_(true) {} 264 component_extensions_auto_granted_(true) {}
266 265
267 SimpleFeature::~SimpleFeature() {} 266 SimpleFeature::~SimpleFeature() {}
268 267
269 bool SimpleFeature::HasDependencies() const { 268 bool SimpleFeature::HasDependencies() const {
270 return !dependencies_.empty(); 269 return !dependencies_.empty();
271 } 270 }
272 271
273 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { 272 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) {
274 filters_.push_back(filter.release()); 273 filters_.push_back(filter.release());
275 } 274 }
276 275
277 std::string SimpleFeature::Parse(const base::DictionaryValue* value) { 276 std::string SimpleFeature::Parse(const base::DictionaryValue* dictionary) {
278 ParseURLPatterns(value, "matches", &matches_); 277 static base::LazyInstance<SimpleFeature::Mappings> mappings =
279 ParseSet(value, "blacklist", &blacklist_); 278 LAZY_INSTANCE_INITIALIZER;
280 ParseSet(value, "whitelist", &whitelist_);
281 ParseSet(value, "dependencies", &dependencies_);
282 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_,
283 g_mappings.Get().extension_types);
284 ParseEnumSet<Context>(value, "contexts", &contexts_,
285 g_mappings.Get().contexts);
286 ParseEnum<Location>(value, "location", &location_,
287 g_mappings.Get().locations);
288 ParseEnumSet<Platform>(value, "platforms", &platforms_,
289 g_mappings.Get().platforms);
290 value->GetInteger("min_manifest_version", &min_manifest_version_);
291 value->GetInteger("max_manifest_version", &max_manifest_version_);
292 279
293 no_parent_ = false; 280 no_parent_ = false;
294 value->GetBoolean("noparent", &no_parent_); 281 for (base::DictionaryValue::Iterator it(*dictionary);
295 282 !it.IsAtEnd();
296 value->GetBoolean("component_extensions_auto_granted", 283 it.Advance()) {
297 &component_extensions_auto_granted_); 284 std::string key = it.key();
298 285 const base::Value* value = &it.value();
299 value->GetString("command_line_switch", &command_line_switch_); 286 if (key == "matches") {
287 ParseURLPatterns(dictionary, "matches", &matches_);
288 } else if (key == "blacklist") {
289 ParseVector(value, &blacklist_);
290 } else if (key == "whitelist") {
291 ParseVector(value, &whitelist_);
292 } else if (key == "dependencies") {
293 ParseVector(value, &dependencies_);
294 } else if (key == "extension_types") {
295 ParseEnumVector<Manifest::Type>(value, &extension_types_,
296 mappings.Get().extension_types);
297 } else if (key == "contexts") {
298 ParseEnumVector<Context>(value, &contexts_,
299 mappings.Get().contexts);
300 } else if (key == "location") {
301 ParseEnum<Location>(dictionary, "location", &location_,
302 mappings.Get().locations);
303 } else if (key == "platforms") {
304 ParseEnumVector<Platform>(value, &platforms_,
305 mappings.Get().platforms);
306 } else if (key == "min_manifest_version") {
307 dictionary->GetInteger("min_manifest_version", &min_manifest_version_);
308 } else if (key == "max_manifest_version") {
309 dictionary->GetInteger("max_manifest_version", &max_manifest_version_);
310 } else if (key == "noparent") {
311 dictionary->GetBoolean("noparent", &no_parent_);
312 } else if (key == "component_extensions_auto_granted") {
313 dictionary->GetBoolean("component_extensions_auto_granted",
314 &component_extensions_auto_granted_);
315 } else if (key == "command_line_switch") {
316 dictionary->GetString("command_line_switch", &command_line_switch_);
317 }
318 }
300 319
301 // NOTE: ideally we'd sanity check that "matches" can be specified if and 320 // NOTE: ideally we'd sanity check that "matches" can be specified if and
302 // only if there's a "web_page" or "webui" context, but without 321 // only if there's a "web_page" or "webui" context, but without
303 // (Simple)Features being aware of their own heirarchy this is impossible. 322 // (Simple)Features being aware of their own heirarchy this is impossible.
304 // 323 //
305 // For example, we might have feature "foo" available to "web_page" context 324 // For example, we might have feature "foo" available to "web_page" context
306 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override 325 // and "matches" google.com/*. Then a sub-feature "foo.bar" might override
307 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify 326 // "matches" to be chromium.org/*. That sub-feature doesn't need to specify
308 // "web_page" context because it's inherited, but we don't know that here. 327 // "web_page" context because it's inherited, but we don't know that here.
309 328
310 std::string result; 329 std::string result;
311 for (const auto& filter : filters_) { 330 for (const auto& filter : filters_) {
312 result = filter->Parse(value); 331 result = filter->Parse(dictionary);
313 if (!result.empty()) 332 if (!result.empty())
314 break; 333 break;
315 } 334 }
316 335
317 return result; 336 return result;
318 } 337 }
319 338
320 Feature::Availability SimpleFeature::IsAvailableToManifest( 339 Feature::Availability SimpleFeature::IsAvailableToManifest(
321 const std::string& extension_id, 340 const std::string& extension_id,
322 Manifest::Type type, 341 Manifest::Type type,
323 Manifest::Location location, 342 Manifest::Location location,
324 int manifest_version, 343 int manifest_version,
325 Platform platform) const { 344 Platform platform) const {
326 // Check extension type first to avoid granting platform app permissions 345 // Check extension type first to avoid granting platform app permissions
327 // to component extensions. 346 // to component extensions.
328 // HACK(kalman): user script -> extension. Solve this in a more generic way 347 // HACK(kalman): user script -> extension. Solve this in a more generic way
329 // when we compile feature files. 348 // when we compile feature files.
330 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? 349 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ?
331 Manifest::TYPE_EXTENSION : type; 350 Manifest::TYPE_EXTENSION : type;
332 if (!extension_types_.empty() && 351 if (!extension_types_.empty() &&
333 !ContainsKey(extension_types_, type_to_check)) { 352 !ContainsValue(extension_types_, type_to_check)) {
334 return CreateAvailability(INVALID_TYPE, type); 353 return CreateAvailability(INVALID_TYPE, type);
335 } 354 }
336 355
337 if (IsIdInBlacklist(extension_id)) 356 if (IsIdInBlacklist(extension_id))
338 return CreateAvailability(FOUND_IN_BLACKLIST, type); 357 return CreateAvailability(FOUND_IN_BLACKLIST, type);
339 358
340 // TODO(benwells): don't grant all component extensions. 359 // TODO(benwells): don't grant all component extensions.
341 // See http://crbug.com/370375 for more details. 360 // See http://crbug.com/370375 for more details.
342 // Component extensions can access any feature. 361 // Component extensions can access any feature.
343 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. 362 // NOTE: Deliberately does not match EXTERNAL_COMPONENT.
(...skipping 12 matching lines...) Expand all
356 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 375 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
357 switches::kWhitelistedExtensionID); 376 switches::kWhitelistedExtensionID);
358 if (extension_id != whitelist_switch_value) 377 if (extension_id != whitelist_switch_value)
359 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 378 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type);
360 } 379 }
361 } 380 }
362 381
363 if (!MatchesManifestLocation(location)) 382 if (!MatchesManifestLocation(location))
364 return CreateAvailability(INVALID_LOCATION, type); 383 return CreateAvailability(INVALID_LOCATION, type);
365 384
366 if (!platforms_.empty() && !ContainsKey(platforms_, platform)) 385 if (!platforms_.empty() && !ContainsValue(platforms_, platform))
367 return CreateAvailability(INVALID_PLATFORM, type); 386 return CreateAvailability(INVALID_PLATFORM, type);
368 387
369 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) 388 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_)
370 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); 389 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type);
371 390
372 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) 391 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_)
373 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); 392 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type);
374 393
375 if (!command_line_switch_.empty() && 394 if (!command_line_switch_.empty() &&
376 !IsCommandLineSwitchEnabled(command_line_switch_)) { 395 !IsCommandLineSwitchEnabled(command_line_switch_)) {
(...skipping 23 matching lines...) Expand all
400 if (extension) { 419 if (extension) {
401 Availability result = IsAvailableToManifest(extension->id(), 420 Availability result = IsAvailableToManifest(extension->id(),
402 extension->GetType(), 421 extension->GetType(),
403 extension->location(), 422 extension->location(),
404 extension->manifest_version(), 423 extension->manifest_version(),
405 platform); 424 platform);
406 if (!result.is_available()) 425 if (!result.is_available())
407 return result; 426 return result;
408 } 427 }
409 428
410 if (!contexts_.empty() && !ContainsKey(contexts_, context)) 429 if (!contexts_.empty() && !ContainsValue(contexts_, context))
411 return CreateAvailability(INVALID_CONTEXT, context); 430 return CreateAvailability(INVALID_CONTEXT, context);
412 431
413 // TODO(kalman): Consider checking |matches_| regardless of context type. 432 // TODO(kalman): Consider checking |matches_| regardless of context type.
414 // Fewer surprises, and if the feature configuration wants to isolate 433 // Fewer surprises, and if the feature configuration wants to isolate
415 // "matches" from say "blessed_extension" then they can use complex features. 434 // "matches" from say "blessed_extension" then they can use complex features.
416 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && 435 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) &&
417 !matches_.MatchesURL(url)) { 436 !matches_.MatchesURL(url)) {
418 return CreateAvailability(INVALID_URL, url); 437 return CreateAvailability(INVALID_URL, url);
419 } 438 }
420 439
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 551
533 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { 552 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const {
534 return IsIdInList(extension_id, blacklist_); 553 return IsIdInList(extension_id, blacklist_);
535 } 554 }
536 555
537 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { 556 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const {
538 return IsIdInList(extension_id, whitelist_); 557 return IsIdInList(extension_id, whitelist_);
539 } 558 }
540 559
541 // static 560 // static
561 bool SimpleFeature::IsIdInArray(const std::string& extension_id,
562 const char* const array[],
563 size_t array_length) {
564 if (!IsValidExtensionId(extension_id))
565 return false;
566
567 const char* const* start = array;
568 const char* const* end = array + array_length;
569
570 return ((std::find(start, end, extension_id) != end) ||
571 (std::find(start, end, HashExtensionId(extension_id)) != end));
572 }
573
574 // static
542 bool SimpleFeature::IsIdInList(const std::string& extension_id, 575 bool SimpleFeature::IsIdInList(const std::string& extension_id,
543 const std::set<std::string>& list) { 576 const std::vector<std::string>& list) {
544 // Belt-and-suspenders philosophy here. We should be pretty confident by this 577 if (!IsValidExtensionId(extension_id))
545 // point that we've validated the extension ID format, but in case something
546 // slips through, we avoid a class of attack where creative ID manipulation
547 // leads to hash collisions.
548 if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters
549 return false; 578 return false;
550 579
551 return (ContainsKey(list, extension_id) || 580 return (ContainsValue(list, extension_id) ||
552 ContainsKey(list, HashExtensionId(extension_id))); 581 ContainsValue(list, HashExtensionId(extension_id)));
553 } 582 }
554 583
555 bool SimpleFeature::MatchesManifestLocation( 584 bool SimpleFeature::MatchesManifestLocation(
556 Manifest::Location manifest_location) const { 585 Manifest::Location manifest_location) const {
557 switch (location_) { 586 switch (location_) {
558 case SimpleFeature::UNSPECIFIED_LOCATION: 587 case SimpleFeature::UNSPECIFIED_LOCATION:
559 return true; 588 return true;
560 case SimpleFeature::COMPONENT_LOCATION: 589 case SimpleFeature::COMPONENT_LOCATION:
561 return manifest_location == Manifest::COMPONENT; 590 return manifest_location == Manifest::COMPONENT;
562 case SimpleFeature::EXTERNAL_COMPONENT_LOCATION: 591 case SimpleFeature::EXTERNAL_COMPONENT_LOCATION:
(...skipping 13 matching lines...) Expand all
576 ExtensionAPI::GetSharedInstance()->GetFeatureDependency(dep_name); 605 ExtensionAPI::GetSharedInstance()->GetFeatureDependency(dep_name);
577 if (!dependency) 606 if (!dependency)
578 return CreateAvailability(NOT_PRESENT); 607 return CreateAvailability(NOT_PRESENT);
579 Availability dependency_availability = checker.Run(dependency); 608 Availability dependency_availability = checker.Run(dependency);
580 if (!dependency_availability.is_available()) 609 if (!dependency_availability.is_available())
581 return dependency_availability; 610 return dependency_availability;
582 } 611 }
583 return CreateAvailability(IS_AVAILABLE); 612 return CreateAvailability(IS_AVAILABLE);
584 } 613 }
585 614
615 // static
616 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) {
617 // Belt-and-suspenders philosophy here. We should be pretty confident by this
618 // point that we've validated the extension ID format, but in case something
619 // slips through, we avoid a class of attack where creative ID manipulation
620 // leads to hash collisions.
621 // 128 bits / 4 = 32 mpdecimal characters
622 return (extension_id.length() == 32);
623 }
624
586 } // namespace extensions 625 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698