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

Side by Side Diff: chrome/common/extensions/extension_permission_set.cc

Issue 7347011: Update URLPatternSet to contain a std::set instead of std::vector. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix windows compile errors. Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/common/extensions/extension_permission_set.h" 5 #include "chrome/common/extensions/extension_permission_set.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/memory/singleton.h" 10 #include "base/memory/singleton.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 "tabs.update", 74 "tabs.update",
75 }; 75 };
76 const size_t kNumNonPermissionFunctionNames = 76 const size_t kNumNonPermissionFunctionNames =
77 arraysize(kNonPermissionFunctionNames); 77 arraysize(kNonPermissionFunctionNames);
78 78
79 const char kOldUnlimitedStoragePermission[] = "unlimited_storage"; 79 const char kOldUnlimitedStoragePermission[] = "unlimited_storage";
80 const char kWindowsPermission[] = "windows"; 80 const char kWindowsPermission[] = "windows";
81 81
82 void AddPatternsAndRemovePaths(const URLPatternSet& set, URLPatternSet* out) { 82 void AddPatternsAndRemovePaths(const URLPatternSet& set, URLPatternSet* out) {
83 CHECK(out); 83 CHECK(out);
84 const URLPatternList& patterns = set.patterns(); 84 for (URLPatternSet::const_iterator i = set.begin(); i != set.end(); ++i) {
85 for (size_t i = 0; i < patterns.size(); ++i) { 85 URLPattern p = *i;
86 URLPattern p = patterns.at(i);
87 p.SetPath("/*"); 86 p.SetPath("/*");
88 out->AddPattern(p); 87 out->AddPattern(p);
89 } 88 }
90 } 89 }
91 90
92 } // namespace 91 } // namespace
93 92
94 // 93 //
95 // PermissionMessage 94 // PermissionMessage
96 // 95 //
97 96
98 // static 97 // static
99 ExtensionPermissionMessage ExtensionPermissionMessage::CreateFromHostList( 98 ExtensionPermissionMessage ExtensionPermissionMessage::CreateFromHostList(
100 const std::vector<std::string>& hosts) { 99 const std::set<std::string>& hosts) {
101 CHECK(hosts.size() > 0); 100 std::vector<std::string> host_list(hosts.begin(), hosts.end());
101 CHECK(host_list.size() > 0);
102 ID message_id; 102 ID message_id;
103 string16 message; 103 string16 message;
104 switch (hosts.size()) { 104
105 switch (host_list.size()) {
105 case 1: 106 case 1:
106 message_id = kHosts1; 107 message_id = kHosts1;
107 message = l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_1_HOST, 108 message = l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_1_HOST,
108 UTF8ToUTF16(hosts[0])); 109 UTF8ToUTF16(host_list[0]));
109 break; 110 break;
110 case 2: 111 case 2:
111 message_id = kHosts2; 112 message_id = kHosts2;
112 message = l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_2_HOSTS, 113 message = l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_2_HOSTS,
113 UTF8ToUTF16(hosts[0]), 114 UTF8ToUTF16(host_list[0]),
114 UTF8ToUTF16(hosts[1])); 115 UTF8ToUTF16(host_list[1]));
115 break; 116 break;
116 case 3: 117 case 3:
117 message_id = kHosts3; 118 message_id = kHosts3;
118 message = l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_3_HOSTS, 119 message = l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_3_HOSTS,
119 UTF8ToUTF16(hosts[0]), 120 UTF8ToUTF16(host_list[0]),
120 UTF8ToUTF16(hosts[1]), 121 UTF8ToUTF16(host_list[1]),
121 UTF8ToUTF16(hosts[2])); 122 UTF8ToUTF16(host_list[2]));
122 break; 123 break;
123 default: 124 default:
124 message_id = kHosts4OrMore; 125 message_id = kHosts4OrMore;
125 message = l10n_util::GetStringFUTF16( 126 message = l10n_util::GetStringFUTF16(
126 IDS_EXTENSION_PROMPT_WARNING_4_OR_MORE_HOSTS, 127 IDS_EXTENSION_PROMPT_WARNING_4_OR_MORE_HOSTS,
127 UTF8ToUTF16(hosts[0]), 128 UTF8ToUTF16(host_list[0]),
128 UTF8ToUTF16(hosts[1]), 129 UTF8ToUTF16(host_list[1]),
129 base::IntToString16(hosts.size() - 2)); 130 base::IntToString16(hosts.size() - 2));
130 break; 131 break;
131 } 132 }
132 133
133 return ExtensionPermissionMessage(message_id, message); 134 return ExtensionPermissionMessage(message_id, message);
134 } 135 }
135 136
136 ExtensionPermissionMessage::ExtensionPermissionMessage( 137 ExtensionPermissionMessage::ExtensionPermissionMessage(
137 ExtensionPermissionMessage::ID id, const string16& message) 138 ExtensionPermissionMessage::ID id, const string16& message)
138 : id_(id), message_(message) { 139 : id_(id), message_(message) {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 std::set<std::string> apis_str; 448 std::set<std::string> apis_str;
448 for (ExtensionAPIPermissionSet::const_iterator i = apis_.begin(); 449 for (ExtensionAPIPermissionSet::const_iterator i = apis_.begin();
449 i != apis_.end(); ++i) { 450 i != apis_.end(); ++i) {
450 ExtensionAPIPermission* permission = info->GetByID(*i); 451 ExtensionAPIPermission* permission = info->GetByID(*i);
451 if (permission) 452 if (permission)
452 apis_str.insert(permission->name()); 453 apis_str.insert(permission->name());
453 } 454 }
454 return apis_str; 455 return apis_str;
455 } 456 }
456 457
457 std::vector<std::string> 458 std::set<std::string>
458 ExtensionPermissionSet::GetDistinctHostsForDisplay() const { 459 ExtensionPermissionSet::GetDistinctHostsForDisplay() const {
459 return GetDistinctHosts(effective_hosts_.patterns(), true); 460 return GetDistinctHosts(effective_hosts_, true);
460 } 461 }
461 462
462 ExtensionPermissionMessages 463 ExtensionPermissionMessages
463 ExtensionPermissionSet::GetPermissionMessages() const { 464 ExtensionPermissionSet::GetPermissionMessages() const {
464 ExtensionPermissionMessages messages; 465 ExtensionPermissionMessages messages;
465 466
466 if (HasEffectiveFullAccess()) { 467 if (HasEffectiveFullAccess()) {
467 messages.push_back(ExtensionPermissionMessage( 468 messages.push_back(ExtensionPermissionMessage(
468 ExtensionPermissionMessage::kFullAccess, 469 ExtensionPermissionMessage::kFullAccess,
469 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS))); 470 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS)));
470 return messages; 471 return messages;
471 } 472 }
472 473
473 if (HasEffectiveAccessToAllHosts()) { 474 if (HasEffectiveAccessToAllHosts()) {
474 messages.push_back(ExtensionPermissionMessage( 475 messages.push_back(ExtensionPermissionMessage(
475 ExtensionPermissionMessage::kHostsAll, 476 ExtensionPermissionMessage::kHostsAll,
476 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS))); 477 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
477 } else { 478 } else {
478 std::vector<std::string> hosts = GetDistinctHostsForDisplay(); 479 std::set<std::string> hosts = GetDistinctHostsForDisplay();
479 if (!hosts.empty()) 480 if (!hosts.empty())
480 messages.push_back(ExtensionPermissionMessage::CreateFromHostList(hosts)); 481 messages.push_back(ExtensionPermissionMessage::CreateFromHostList(hosts));
481 } 482 }
482 483
483 std::set<ExtensionPermissionMessage> simple_msgs = 484 std::set<ExtensionPermissionMessage> simple_msgs =
484 GetSimplePermissionMessages(); 485 GetSimplePermissionMessages();
485 messages.insert(messages.end(), simple_msgs.begin(), simple_msgs.end()); 486 messages.insert(messages.end(), simple_msgs.begin(), simple_msgs.end());
486 487
487 return messages; 488 return messages;
488 } 489 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 // We only need to check our host list to verify access. The host list should 555 // We only need to check our host list to verify access. The host list should
555 // already reflect any special rules (such as chrome://favicon, component 556 // already reflect any special rules (such as chrome://favicon, component
556 // all hosts access, etc.). 557 // all hosts access, etc.).
557 return scriptable_hosts().MatchesURL(origin); 558 return scriptable_hosts().MatchesURL(origin);
558 } 559 }
559 560
560 bool ExtensionPermissionSet::HasEffectiveAccessToAllHosts() const { 561 bool ExtensionPermissionSet::HasEffectiveAccessToAllHosts() const {
561 // There are two ways this set can have effective access to all hosts: 562 // There are two ways this set can have effective access to all hosts:
562 // 1) it has an <all_urls> URL pattern. 563 // 1) it has an <all_urls> URL pattern.
563 // 2) it has a named permission with implied full URL access. 564 // 2) it has a named permission with implied full URL access.
564 const URLPatternList patterns = effective_hosts().patterns(); 565 for (URLPatternSet::const_iterator host = effective_hosts().begin();
565 for (URLPatternList::const_iterator host = patterns.begin(); 566 host != effective_hosts().end(); ++host) {
566 host != patterns.end(); ++host) {
567 if (host->match_all_urls() || 567 if (host->match_all_urls() ||
568 (host->match_subdomains() && host->host().empty())) 568 (host->match_subdomains() && host->host().empty()))
569 return true; 569 return true;
570 } 570 }
571 571
572 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); 572 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance();
573 for (ExtensionAPIPermissionSet::const_iterator i = apis().begin(); 573 for (ExtensionAPIPermissionSet::const_iterator i = apis().begin();
574 i != apis().end(); ++i) { 574 i != apis().end(); ++i) {
575 ExtensionAPIPermission* permission = info->GetByID(*i); 575 ExtensionAPIPermission* permission = info->GetByID(*i);
576 if (permission->implies_full_url_access()) 576 if (permission->implies_full_url_access())
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 if (HasLessHostPrivilegesThan(permissions)) 619 if (HasLessHostPrivilegesThan(permissions))
620 return true; 620 return true;
621 621
622 if (HasLessAPIPrivilegesThan(permissions)) 622 if (HasLessAPIPrivilegesThan(permissions))
623 return true; 623 return true;
624 624
625 return false; 625 return false;
626 } 626 }
627 627
628 // static 628 // static
629 std::vector<std::string> ExtensionPermissionSet::GetDistinctHosts( 629 std::set<std::string> ExtensionPermissionSet::GetDistinctHosts(
630 const URLPatternList& host_patterns, bool include_rcd) { 630 const URLPatternSet& host_patterns, bool include_rcd) {
631 // Use a vector to preserve order (also faster than a map on small sets). 631 // Use a vector to preserve order (also faster than a map on small sets).
632 // Each item is a host split into two parts: host without RCDs and 632 // Each item is a host split into two parts: host without RCDs and
633 // current best RCD. 633 // current best RCD.
634 typedef std::vector<std::pair<std::string, std::string> > HostVector; 634 typedef std::vector<std::pair<std::string, std::string> > HostVector;
635 HostVector hosts_best_rcd; 635 HostVector hosts_best_rcd;
636 for (size_t i = 0; i < host_patterns.size(); ++i) { 636 for (URLPatternSet::const_iterator i = host_patterns.begin();
637 std::string host = host_patterns[i].host(); 637 i != host_patterns.end(); ++i) {
638 std::string host = i->host();
638 639
639 // Add the subdomain wildcard back to the host, if necessary. 640 // Add the subdomain wildcard back to the host, if necessary.
640 if (host_patterns[i].match_subdomains()) 641 if (i->match_subdomains())
641 host = "*." + host; 642 host = "*." + host;
642 643
643 // If the host has an RCD, split it off so we can detect duplicates. 644 // If the host has an RCD, split it off so we can detect duplicates.
644 std::string rcd; 645 std::string rcd;
645 size_t reg_len = net::RegistryControlledDomainService::GetRegistryLength( 646 size_t reg_len = net::RegistryControlledDomainService::GetRegistryLength(
646 host, false); 647 host, false);
647 if (reg_len && reg_len != std::string::npos) { 648 if (reg_len && reg_len != std::string::npos) {
648 if (include_rcd) // else leave rcd empty 649 if (include_rcd) // else leave rcd empty
649 rcd = host.substr(host.size() - reg_len); 650 rcd = host.substr(host.size() - reg_len);
650 host = host.substr(0, host.size() - reg_len); 651 host = host.substr(0, host.size() - reg_len);
651 } 652 }
652 653
653 // Check if we've already seen this host. 654 // Check if we've already seen this host.
654 HostVector::iterator it = hosts_best_rcd.begin(); 655 HostVector::iterator it = hosts_best_rcd.begin();
655 for (; it != hosts_best_rcd.end(); ++it) { 656 for (; it != hosts_best_rcd.end(); ++it) {
656 if (it->first == host) 657 if (it->first == host)
657 break; 658 break;
658 } 659 }
659 // If this host was found, replace the RCD if this one is better. 660 // If this host was found, replace the RCD if this one is better.
660 if (it != hosts_best_rcd.end()) { 661 if (it != hosts_best_rcd.end()) {
661 if (include_rcd && RcdBetterThan(rcd, it->second)) 662 if (include_rcd && RcdBetterThan(rcd, it->second))
662 it->second = rcd; 663 it->second = rcd;
663 } else { // Previously unseen host, append it. 664 } else { // Previously unseen host, append it.
664 hosts_best_rcd.push_back(std::make_pair(host, rcd)); 665 hosts_best_rcd.push_back(std::make_pair(host, rcd));
665 } 666 }
666 } 667 }
667 668
668 // Build up the final vector by concatenating hosts and RCDs. 669 // Build up the final vector by concatenating hosts and RCDs.
669 std::vector<std::string> distinct_hosts; 670 std::set<std::string> distinct_hosts;
670 for (HostVector::iterator it = hosts_best_rcd.begin(); 671 for (HostVector::iterator it = hosts_best_rcd.begin();
671 it != hosts_best_rcd.end(); ++it) 672 it != hosts_best_rcd.end(); ++it)
672 distinct_hosts.push_back(it->first + it->second); 673 distinct_hosts.insert(it->first + it->second);
673 return distinct_hosts; 674 return distinct_hosts;
674 } 675 }
675 676
676 void ExtensionPermissionSet::InitEffectiveHosts() { 677 void ExtensionPermissionSet::InitEffectiveHosts() {
677 effective_hosts_.ClearPatterns(); 678 effective_hosts_.ClearPatterns();
678 679
679 if (HasEffectiveAccessToAllHosts()) { 680 if (HasEffectiveAccessToAllHosts()) {
680 URLPattern all_urls(URLPattern::SCHEME_ALL); 681 URLPattern all_urls(URLPattern::SCHEME_ALL);
681 all_urls.set_match_all_urls(true); 682 all_urls.SetMatchAllURLs(true);
682 effective_hosts_.AddPattern(all_urls); 683 effective_hosts_.AddPattern(all_urls);
683 return; 684 return;
684 } 685 }
685 686
686 URLPatternSet::CreateUnion( 687 URLPatternSet::CreateUnion(
687 explicit_hosts(), scriptable_hosts(), &effective_hosts_); 688 explicit_hosts(), scriptable_hosts(), &effective_hosts_);
688 } 689 }
689 690
690 void ExtensionPermissionSet::InitImplicitExtensionPermissions( 691 void ExtensionPermissionSet::InitImplicitExtensionPermissions(
691 const Extension* extension) { 692 const Extension* extension) {
692 // Add the implied permissions. 693 // Add the implied permissions.
693 if (!extension->plugins().empty()) 694 if (!extension->plugins().empty())
694 apis_.insert(ExtensionAPIPermission::kPlugin); 695 apis_.insert(ExtensionAPIPermission::kPlugin);
695 696
696 if (!extension->devtools_url().is_empty()) 697 if (!extension->devtools_url().is_empty())
697 apis_.insert(ExtensionAPIPermission::kDevtools); 698 apis_.insert(ExtensionAPIPermission::kDevtools);
698 699
699 // Add the scriptable hosts. 700 // Add the scriptable hosts.
700 for (UserScriptList::const_iterator content_script = 701 for (UserScriptList::const_iterator content_script =
701 extension->content_scripts().begin(); 702 extension->content_scripts().begin();
702 content_script != extension->content_scripts().end(); ++content_script) { 703 content_script != extension->content_scripts().end(); ++content_script) {
703 URLPatternList::const_iterator pattern = 704 URLPatternSet::const_iterator pattern =
704 content_script->url_patterns().begin(); 705 content_script->url_patterns().begin();
705 for (; pattern != content_script->url_patterns().end(); ++pattern) 706 for (; pattern != content_script->url_patterns().end(); ++pattern)
706 scriptable_hosts_.AddPattern(*pattern); 707 scriptable_hosts_.AddPattern(*pattern);
707 } 708 }
708 } 709 }
709 710
710 std::set<ExtensionPermissionMessage> 711 std::set<ExtensionPermissionMessage>
711 ExtensionPermissionSet::GetSimplePermissionMessages() const { 712 ExtensionPermissionSet::GetSimplePermissionMessages() const {
712 std::set<ExtensionPermissionMessage> messages; 713 std::set<ExtensionPermissionMessage> messages;
713 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); 714 ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 const ExtensionPermissionSet* permissions) const { 751 const ExtensionPermissionSet* permissions) const {
751 // If this permission set can access any host, then it can't be elevated. 752 // If this permission set can access any host, then it can't be elevated.
752 if (HasEffectiveAccessToAllHosts()) 753 if (HasEffectiveAccessToAllHosts())
753 return false; 754 return false;
754 755
755 // Likewise, if the other permission set has full host access, then it must be 756 // Likewise, if the other permission set has full host access, then it must be
756 // a privilege increase. 757 // a privilege increase.
757 if (permissions->HasEffectiveAccessToAllHosts()) 758 if (permissions->HasEffectiveAccessToAllHosts())
758 return true; 759 return true;
759 760
760 const URLPatternList old_list = effective_hosts().patterns(); 761 const URLPatternSet& old_list = effective_hosts();
761 const URLPatternList new_list = permissions->effective_hosts().patterns(); 762 const URLPatternSet& new_list = permissions->effective_hosts();
762 763
763 // TODO(jstritar): This is overly conservative with respect to subdomains. 764 // TODO(jstritar): This is overly conservative with respect to subdomains.
764 // For example, going from *.google.com to www.google.com will be 765 // For example, going from *.google.com to www.google.com will be
765 // considered an elevation, even though it is not (http://crbug.com/65337). 766 // considered an elevation, even though it is not (http://crbug.com/65337).
766 std::vector<std::string> new_hosts = GetDistinctHosts(new_list, false); 767 std::set<std::string> new_hosts_set = GetDistinctHosts(new_list, false);
767 std::vector<std::string> old_hosts = GetDistinctHosts(old_list, false); 768 std::set<std::string> old_hosts_set = GetDistinctHosts(old_list, false);
768
769 std::set<std::string> old_hosts_set(old_hosts.begin(), old_hosts.end());
770 std::set<std::string> new_hosts_set(new_hosts.begin(), new_hosts.end());
771 std::set<std::string> new_hosts_only; 769 std::set<std::string> new_hosts_only;
772 770
773 std::set_difference(new_hosts_set.begin(), new_hosts_set.end(), 771 std::set_difference(new_hosts_set.begin(), new_hosts_set.end(),
774 old_hosts_set.begin(), old_hosts_set.end(), 772 old_hosts_set.begin(), old_hosts_set.end(),
775 std::inserter(new_hosts_only, new_hosts_only.begin())); 773 std::inserter(new_hosts_only, new_hosts_only.begin()));
776 774
777 return !new_hosts_only.empty(); 775 return !new_hosts_only.empty();
778 } 776 }
OLDNEW
« no previous file with comments | « chrome/common/extensions/extension_permission_set.h ('k') | chrome/common/extensions/extension_permission_set_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698