OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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.h" | 5 #include "chrome/common/extensions/extension.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
(...skipping 3302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3313 if (browser_action()) | 3313 if (browser_action()) |
3314 ++num_surfaces; | 3314 ++num_surfaces; |
3315 | 3315 |
3316 if (is_app()) | 3316 if (is_app()) |
3317 ++num_surfaces; | 3317 ++num_surfaces; |
3318 | 3318 |
3319 return num_surfaces > 1; | 3319 return num_surfaces > 1; |
3320 } | 3320 } |
3321 | 3321 |
3322 bool Extension::CanExecuteScriptOnPage(const GURL& page_url, | 3322 bool Extension::CanExecuteScriptOnPage(const GURL& page_url, |
3323 int tab_id, | |
3323 const UserScript* script, | 3324 const UserScript* script, |
3324 std::string* error) const { | 3325 std::string* error) const { |
3325 base::AutoLock auto_lock(runtime_data_lock_); | 3326 base::AutoLock auto_lock(runtime_data_lock_); |
3326 // The gallery is special-cased as a restricted URL for scripting to prevent | 3327 // The gallery is special-cased as a restricted URL for scripting to prevent |
3327 // access to special JS bindings we expose to the gallery (and avoid things | 3328 // access to special JS bindings we expose to the gallery (and avoid things |
3328 // like extensions removing the "report abuse" link). | 3329 // like extensions removing the "report abuse" link). |
3329 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing | 3330 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing |
3330 // against the store app extent? | 3331 // against the store app extent? |
3331 GURL store_url(extension_urls::GetWebstoreLaunchURL()); | 3332 GURL store_url(extension_urls::GetWebstoreLaunchURL()); |
3332 if ((page_url.host() == store_url.host()) && | 3333 if ((page_url.host() == store_url.host()) && |
3333 !CanExecuteScriptEverywhere() && | 3334 !CanExecuteScriptEverywhere() && |
3334 !CommandLine::ForCurrentProcess()->HasSwitch( | 3335 !CommandLine::ForCurrentProcess()->HasSwitch( |
3335 switches::kAllowScriptingGallery)) { | 3336 switches::kAllowScriptingGallery)) { |
3336 if (error) | 3337 if (error) |
3337 *error = errors::kCannotScriptGallery; | 3338 *error = errors::kCannotScriptGallery; |
3338 return false; | 3339 return false; |
3339 } | 3340 } |
3340 | 3341 |
3341 if (page_url.SchemeIs(chrome::kChromeUIScheme) && | 3342 if (page_url.SchemeIs(chrome::kChromeUIScheme) && |
3342 !CanExecuteScriptEverywhere()) | 3343 !CanExecuteScriptEverywhere()) |
3343 return false; | 3344 return false; |
3344 | 3345 |
3346 // If a tab ID is specified, try the tab-specific permissions. | |
3347 if (tab_id >= 0) { | |
3348 const URLPatternSet* tab = | |
Aaron Boodman
2012/06/06 01:03:13
nit: tab_permissions?
not at google - send to devlin
2012/06/06 07:38:40
But then it won't fit on 1 line!
| |
3349 runtime_data_.GetTabSpecificHostPermissions(tab_id); | |
3350 if (tab && tab->MatchesSecurityOrigin(page_url)) | |
3351 return true; | |
3352 } | |
3353 | |
3345 // If a script is specified, use its matches. | 3354 // If a script is specified, use its matches. |
3346 if (script) | 3355 if (script) |
3347 return script->MatchesURL(page_url); | 3356 return script->MatchesURL(page_url); |
3348 | 3357 |
3349 // Otherwise, see if this extension has permission to execute script | 3358 // Otherwise, see if this extension has permission to execute script |
3350 // programmatically on pages. | 3359 // programmatically on pages. |
3351 if (runtime_data_.GetActivePermissions()->HasExplicitAccessToOrigin( | 3360 if (runtime_data_.GetActivePermissions()->HasExplicitAccessToOrigin( |
3352 page_url)) | 3361 page_url)) |
3353 return true; | 3362 return true; |
3354 | 3363 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3397 it != whitelist->end(); ++it) { | 3406 it != whitelist->end(); ++it) { |
3398 if (id() == *it) { | 3407 if (id() == *it) { |
3399 return true; | 3408 return true; |
3400 } | 3409 } |
3401 } | 3410 } |
3402 | 3411 |
3403 return false; | 3412 return false; |
3404 } | 3413 } |
3405 | 3414 |
3406 bool Extension::CanCaptureVisiblePage(const GURL& page_url, | 3415 bool Extension::CanCaptureVisiblePage(const GURL& page_url, |
3416 int tab_id, | |
3407 std::string *error) const { | 3417 std::string *error) const { |
3418 if (tab_id >= 0) { | |
3419 const URLPatternSet* tab = GetTabSpecificHostPermissions(tab_id); | |
3420 if (tab && tab->MatchesSecurityOrigin(page_url)) | |
3421 return true; | |
3422 } | |
3423 | |
3408 if (HasHostPermission(page_url) || page_url.GetOrigin() == url()) | 3424 if (HasHostPermission(page_url) || page_url.GetOrigin() == url()) |
3409 return true; | 3425 return true; |
3410 | 3426 |
3411 if (error) { | 3427 if (error) { |
3412 *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, | 3428 *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, |
3413 page_url.spec()); | 3429 page_url.spec()); |
3414 } | 3430 } |
3415 return false; | 3431 return false; |
3416 } | 3432 } |
3417 | 3433 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3573 script_badge_->SetIcon(kDefaultTabId, icon); | 3589 script_badge_->SetIcon(kDefaultTabId, icon); |
3574 | 3590 |
3575 std::string title = browser_action()->GetTitle(kDefaultTabId); | 3591 std::string title = browser_action()->GetTitle(kDefaultTabId); |
3576 if (!title.empty()) | 3592 if (!title.empty()) |
3577 script_badge_->SetTitle(kDefaultTabId, title); | 3593 script_badge_->SetTitle(kDefaultTabId, title); |
3578 } | 3594 } |
3579 | 3595 |
3580 return script_badge_.get(); | 3596 return script_badge_.get(); |
3581 } | 3597 } |
3582 | 3598 |
3599 const URLPatternSet* Extension::GetTabSpecificHostPermissions( | |
3600 int tab_id) const { | |
3601 base::AutoLock auto_lock(runtime_data_lock_); | |
3602 return runtime_data_.GetTabSpecificHostPermissions(tab_id); | |
3603 } | |
3604 | |
3605 void Extension::SetTabSpecificHostPermissions( | |
3606 int tab_id, | |
3607 const URLPatternSet& permissions) const { | |
3608 base::AutoLock auto_lock(runtime_data_lock_); | |
3609 runtime_data_.SetTabSpecificHostPermissions(tab_id, permissions); | |
3610 } | |
3611 | |
3612 void Extension::ClearTabSpecificHostPermissions(int tab_id) const { | |
3613 base::AutoLock auto_lock(runtime_data_lock_); | |
3614 runtime_data_.ClearTabSpecificHostPermissions(tab_id); | |
3615 } | |
3616 | |
3617 const URLPatternSet* Extension::GetActiveHostPermissionsForAllTabs() const { | |
3618 base::AutoLock auto_lock(runtime_data_lock_); | |
3619 return runtime_data_.GetActiveHostPermissionsForAllTabs(); | |
3620 } | |
3621 | |
3622 void Extension::GetAllTabSpecificHostPermissions( | |
3623 std::map<int, URLPatternSet>* out) const { | |
3624 base::AutoLock auto_lock(runtime_data_lock_); | |
3625 runtime_data_.GetAllTabSpecificHostPermissions(out); | |
3626 } | |
3627 | |
3628 void Extension::SetAllTabSpecificHostPermissions( | |
3629 const std::map<int, URLPatternSet>& origins) const { | |
3630 base::AutoLock auto_lock(runtime_data_lock_); | |
3631 runtime_data_.SetAllTabSpecificHostPermissions(origins); | |
3632 } | |
3633 | |
3583 bool Extension::CheckPlatformAppFeatures(std::string* utf8_error) { | 3634 bool Extension::CheckPlatformAppFeatures(std::string* utf8_error) { |
3584 if (!is_platform_app()) | 3635 if (!is_platform_app()) |
3585 return true; | 3636 return true; |
3586 | 3637 |
3587 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 3638 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
3588 switches::kEnablePlatformApps)) { | 3639 switches::kEnablePlatformApps)) { |
3589 *utf8_error = errors::kPlatformAppFlagRequired; | 3640 *utf8_error = errors::kPlatformAppFlagRequired; |
3590 return false; | 3641 return false; |
3591 } | 3642 } |
3592 | 3643 |
(...skipping 23 matching lines...) Expand all Loading... | |
3616 Extension::RuntimeData::~RuntimeData() {} | 3667 Extension::RuntimeData::~RuntimeData() {} |
3617 | 3668 |
3618 scoped_refptr<const ExtensionPermissionSet> | 3669 scoped_refptr<const ExtensionPermissionSet> |
3619 Extension::RuntimeData::GetActivePermissions() const { | 3670 Extension::RuntimeData::GetActivePermissions() const { |
3620 return active_permissions_; | 3671 return active_permissions_; |
3621 } | 3672 } |
3622 | 3673 |
3623 void Extension::RuntimeData::SetActivePermissions( | 3674 void Extension::RuntimeData::SetActivePermissions( |
3624 const ExtensionPermissionSet* active) { | 3675 const ExtensionPermissionSet* active) { |
3625 active_permissions_ = active; | 3676 active_permissions_ = active; |
3677 active_host_permissions_for_all_tabs_.reset(); | |
3678 } | |
3679 | |
3680 const URLPatternSet* | |
3681 Extension::RuntimeData::GetTabSpecificHostPermissions(int tab_id) const { | |
3682 CHECK_GE(tab_id, 0); | |
3683 TabHostPermissionsMap::const_iterator it = | |
3684 tab_specific_host_permissions_.find(tab_id); | |
3685 return (it != tab_specific_host_permissions_.end()) ? it->second.get() : NULL; | |
3686 } | |
3687 | |
3688 void Extension::RuntimeData::SetTabSpecificHostPermissions( | |
3689 int tab_id, | |
3690 const URLPatternSet& hosts) { | |
3691 CHECK_GE(tab_id, 0); | |
3692 tab_specific_host_permissions_[tab_id] = | |
3693 make_linked_ptr(new URLPatternSet(hosts)); | |
3694 | |
3695 // If we're tracking the active host permissions for all tabs, update it. | |
3696 if (active_host_permissions_for_all_tabs_.get()) { | |
3697 scoped_ptr<URLPatternSet> updated(new URLPatternSet()); | |
3698 URLPatternSet::CreateUnion(*active_host_permissions_for_all_tabs_, | |
3699 hosts, | |
3700 updated.get()); | |
3701 active_host_permissions_for_all_tabs_ = updated.Pass(); | |
3702 } | |
3703 } | |
3704 | |
3705 void Extension::RuntimeData::ClearTabSpecificHostPermissions(int tab_id) { | |
3706 CHECK_GE(tab_id, 0); | |
3707 tab_specific_host_permissions_.erase(tab_id); | |
3708 active_host_permissions_for_all_tabs_.reset(); | |
3709 } | |
3710 | |
3711 const URLPatternSet* | |
3712 Extension::RuntimeData::GetActiveHostPermissionsForAllTabs() const { | |
3713 if (active_host_permissions_for_all_tabs_.get()) | |
3714 return active_host_permissions_for_all_tabs_.get(); | |
3715 | |
3716 if (tab_specific_host_permissions_.empty()) | |
3717 return &active_permissions_->explicit_hosts(); | |
3718 | |
3719 // Compute and cache the union of all tab specific permissions. The union | |
3720 // operation for ExtensionPermissionSet is O(n), so the naive union | |
3721 // implementation would be O(n^2). Try to be smarter and do it in O(nlog(n)). | |
3722 std::vector<linked_ptr<const URLPatternSet> > all; | |
3723 for (TabHostPermissionsMap::const_iterator it = | |
3724 tab_specific_host_permissions_.begin(); | |
3725 it != tab_specific_host_permissions_.end(); ++it) { | |
3726 all.push_back(it->second); | |
3727 } | |
3728 | |
3729 for (size_t skip = 1; skip < all.size(); skip *= 2) { | |
3730 for (size_t i = 0; i < all.size() - skip; i += skip) { | |
3731 URLPatternSet* u = new URLPatternSet(); | |
3732 URLPatternSet::CreateUnion(*all[i], *all[i + skip], u); | |
3733 all[i] = make_linked_ptr(u); | |
3734 } | |
3735 } | |
3736 | |
3737 active_host_permissions_for_all_tabs_.reset(new URLPatternSet()); | |
3738 URLPatternSet::CreateUnion( | |
3739 *all[0], | |
3740 active_permissions_->explicit_hosts(), | |
3741 active_host_permissions_for_all_tabs_.get()); | |
3742 return active_host_permissions_for_all_tabs_.get(); | |
3743 } | |
3744 | |
3745 void Extension::RuntimeData::GetAllTabSpecificHostPermissions( | |
3746 std::map<int, URLPatternSet>* out) const { | |
3747 for (TabHostPermissionsMap::const_iterator it = | |
3748 tab_specific_host_permissions_.begin(); | |
3749 it != tab_specific_host_permissions_.end(); ++it) { | |
3750 (*out)[it->first] = *it->second; | |
3751 } | |
3752 } | |
3753 | |
3754 void Extension::RuntimeData::SetAllTabSpecificHostPermissions( | |
3755 const std::map<int, URLPatternSet>& in) { | |
3756 tab_specific_host_permissions_.clear(); | |
3757 active_host_permissions_for_all_tabs_.reset(); | |
3758 | |
3759 for (std::map<int, URLPatternSet>::const_iterator it = in.begin(); | |
3760 it != in.end(); ++it) { | |
3761 tab_specific_host_permissions_[it->first].reset( | |
3762 new URLPatternSet(it->second)); | |
3763 } | |
3626 } | 3764 } |
3627 | 3765 |
3628 UnloadedExtensionInfo::UnloadedExtensionInfo( | 3766 UnloadedExtensionInfo::UnloadedExtensionInfo( |
3629 const Extension* extension, | 3767 const Extension* extension, |
3630 extension_misc::UnloadedExtensionReason reason) | 3768 extension_misc::UnloadedExtensionReason reason) |
3631 : reason(reason), | 3769 : reason(reason), |
3632 already_disabled(false), | 3770 already_disabled(false), |
3633 extension(extension) {} | 3771 extension(extension) {} |
3634 | 3772 |
3635 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3773 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
3636 const Extension* extension, | 3774 const Extension* extension, |
3637 const ExtensionPermissionSet* permissions, | 3775 const ExtensionPermissionSet* permissions, |
3638 Reason reason) | 3776 Reason reason) |
3639 : reason(reason), | 3777 : reason(reason), |
3640 extension(extension), | 3778 extension(extension), |
3641 permissions(permissions) {} | 3779 permissions(permissions) {} |
3642 | 3780 |
3643 } // namespace extensions | 3781 } // namespace extensions |
OLD | NEW |