| Index: chrome/common/extensions/extension.cc
|
| diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
|
| index 54e056617ede1fb55352371f612050bdb4ffb5de..f83e71a20ece445b177726e76f465b8242098df3 100644
|
| --- a/chrome/common/extensions/extension.cc
|
| +++ b/chrome/common/extensions/extension.cc
|
| @@ -3320,6 +3320,7 @@ bool Extension::HasMultipleUISurfaces() const {
|
| }
|
|
|
| bool Extension::CanExecuteScriptOnPage(const GURL& page_url,
|
| + int tab_id,
|
| const UserScript* script,
|
| std::string* error) const {
|
| base::AutoLock auto_lock(runtime_data_lock_);
|
| @@ -3342,6 +3343,16 @@ bool Extension::CanExecuteScriptOnPage(const GURL& page_url,
|
| !CanExecuteScriptEverywhere())
|
| return false;
|
|
|
| + // If a tab ID is specified, try the tab-specific permissions.
|
| + if (tab_id >= 0) {
|
| + const URLPatternSet* tab_permissions =
|
| + runtime_data_.GetTabSpecificHostPermissions(tab_id);
|
| + if (tab_permissions &&
|
| + tab_permissions->MatchesSecurityOrigin(page_url)) {
|
| + return true;
|
| + }
|
| + }
|
| +
|
| // If a script is specified, use its matches.
|
| if (script)
|
| return script->MatchesURL(page_url);
|
| @@ -3404,7 +3415,14 @@ bool Extension::CanExecuteScriptEverywhere() const {
|
| }
|
|
|
| bool Extension::CanCaptureVisiblePage(const GURL& page_url,
|
| + int tab_id,
|
| std::string *error) const {
|
| + if (tab_id >= 0) {
|
| + const URLPatternSet* tab = GetTabSpecificHostPermissions(tab_id);
|
| + if (tab && tab->MatchesSecurityOrigin(page_url))
|
| + return true;
|
| + }
|
| +
|
| if (HasHostPermission(page_url) || page_url.GetOrigin() == url())
|
| return true;
|
|
|
| @@ -3580,6 +3598,41 @@ ExtensionAction* Extension::GetScriptBadge() const {
|
| return script_badge_.get();
|
| }
|
|
|
| +const URLPatternSet* Extension::GetTabSpecificHostPermissions(
|
| + int tab_id) const {
|
| + base::AutoLock auto_lock(runtime_data_lock_);
|
| + return runtime_data_.GetTabSpecificHostPermissions(tab_id);
|
| +}
|
| +
|
| +void Extension::SetTabSpecificHostPermissions(
|
| + int tab_id,
|
| + const URLPatternSet& permissions) const {
|
| + base::AutoLock auto_lock(runtime_data_lock_);
|
| + runtime_data_.SetTabSpecificHostPermissions(tab_id, permissions);
|
| +}
|
| +
|
| +void Extension::ClearTabSpecificHostPermissions(int tab_id) const {
|
| + base::AutoLock auto_lock(runtime_data_lock_);
|
| + runtime_data_.ClearTabSpecificHostPermissions(tab_id);
|
| +}
|
| +
|
| +const URLPatternSet* Extension::GetActiveHostPermissionsForAllTabs() const {
|
| + base::AutoLock auto_lock(runtime_data_lock_);
|
| + return runtime_data_.GetActiveHostPermissionsForAllTabs();
|
| +}
|
| +
|
| +void Extension::GetAllTabSpecificHostPermissions(
|
| + std::map<int, URLPatternSet>* out) const {
|
| + base::AutoLock auto_lock(runtime_data_lock_);
|
| + runtime_data_.GetAllTabSpecificHostPermissions(out);
|
| +}
|
| +
|
| +void Extension::SetAllTabSpecificHostPermissions(
|
| + const std::map<int, URLPatternSet>& origins) const {
|
| + base::AutoLock auto_lock(runtime_data_lock_);
|
| + runtime_data_.SetAllTabSpecificHostPermissions(origins);
|
| +}
|
| +
|
| bool Extension::CheckPlatformAppFeatures(std::string* utf8_error) {
|
| if (!is_platform_app())
|
| return true;
|
| @@ -3623,6 +3676,93 @@ scoped_refptr<const ExtensionPermissionSet>
|
| void Extension::RuntimeData::SetActivePermissions(
|
| const ExtensionPermissionSet* active) {
|
| active_permissions_ = active;
|
| + active_host_permissions_for_all_tabs_.reset();
|
| +}
|
| +
|
| +const URLPatternSet*
|
| + Extension::RuntimeData::GetTabSpecificHostPermissions(int tab_id) const {
|
| + CHECK_GE(tab_id, 0);
|
| + TabHostPermissionsMap::const_iterator it =
|
| + tab_specific_host_permissions_.find(tab_id);
|
| + return (it != tab_specific_host_permissions_.end()) ? it->second.get() : NULL;
|
| +}
|
| +
|
| +void Extension::RuntimeData::SetTabSpecificHostPermissions(
|
| + int tab_id,
|
| + const URLPatternSet& hosts) {
|
| + CHECK_GE(tab_id, 0);
|
| + tab_specific_host_permissions_[tab_id] =
|
| + make_linked_ptr(new URLPatternSet(hosts));
|
| +
|
| + // If we're tracking the active host permissions for all tabs, update it.
|
| + if (active_host_permissions_for_all_tabs_.get()) {
|
| + scoped_ptr<URLPatternSet> updated(new URLPatternSet());
|
| + URLPatternSet::CreateUnion(*active_host_permissions_for_all_tabs_,
|
| + hosts,
|
| + updated.get());
|
| + active_host_permissions_for_all_tabs_ = updated.Pass();
|
| + }
|
| +}
|
| +
|
| +void Extension::RuntimeData::ClearTabSpecificHostPermissions(int tab_id) {
|
| + CHECK_GE(tab_id, 0);
|
| + tab_specific_host_permissions_.erase(tab_id);
|
| + active_host_permissions_for_all_tabs_.reset();
|
| +}
|
| +
|
| +const URLPatternSet*
|
| + Extension::RuntimeData::GetActiveHostPermissionsForAllTabs() const {
|
| + if (active_host_permissions_for_all_tabs_.get())
|
| + return active_host_permissions_for_all_tabs_.get();
|
| +
|
| + if (tab_specific_host_permissions_.empty())
|
| + return &active_permissions_->explicit_hosts();
|
| +
|
| + // Compute and cache the union of all tab specific permissions. The union
|
| + // operation for ExtensionPermissionSet is O(n), so the naive union
|
| + // implementation would be O(n^2). Try to be smarter and do it in O(nlog(n)).
|
| + std::vector<linked_ptr<const URLPatternSet> > all;
|
| + for (TabHostPermissionsMap::const_iterator it =
|
| + tab_specific_host_permissions_.begin();
|
| + it != tab_specific_host_permissions_.end(); ++it) {
|
| + all.push_back(it->second);
|
| + }
|
| +
|
| + for (size_t skip = 1; skip < all.size(); skip *= 2) {
|
| + for (size_t i = 0; i < all.size() - skip; i += skip) {
|
| + URLPatternSet* u = new URLPatternSet();
|
| + URLPatternSet::CreateUnion(*all[i], *all[i + skip], u);
|
| + all[i] = make_linked_ptr(u);
|
| + }
|
| + }
|
| +
|
| + active_host_permissions_for_all_tabs_.reset(new URLPatternSet());
|
| + URLPatternSet::CreateUnion(
|
| + *all[0],
|
| + active_permissions_->explicit_hosts(),
|
| + active_host_permissions_for_all_tabs_.get());
|
| + return active_host_permissions_for_all_tabs_.get();
|
| +}
|
| +
|
| +void Extension::RuntimeData::GetAllTabSpecificHostPermissions(
|
| + std::map<int, URLPatternSet>* out) const {
|
| + for (TabHostPermissionsMap::const_iterator it =
|
| + tab_specific_host_permissions_.begin();
|
| + it != tab_specific_host_permissions_.end(); ++it) {
|
| + (*out)[it->first] = *it->second;
|
| + }
|
| +}
|
| +
|
| +void Extension::RuntimeData::SetAllTabSpecificHostPermissions(
|
| + const std::map<int, URLPatternSet>& in) {
|
| + tab_specific_host_permissions_.clear();
|
| + active_host_permissions_for_all_tabs_.reset();
|
| +
|
| + for (std::map<int, URLPatternSet>::const_iterator it = in.begin();
|
| + it != in.end(); ++it) {
|
| + tab_specific_host_permissions_[it->first].reset(
|
| + new URLPatternSet(it->second));
|
| + }
|
| }
|
|
|
| UnloadedExtensionInfo::UnloadedExtensionInfo(
|
|
|