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 3370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3381 if (browser_action()) | 3381 if (browser_action()) |
3382 ++num_surfaces; | 3382 ++num_surfaces; |
3383 | 3383 |
3384 if (is_app()) | 3384 if (is_app()) |
3385 ++num_surfaces; | 3385 ++num_surfaces; |
3386 | 3386 |
3387 return num_surfaces > 1; | 3387 return num_surfaces > 1; |
3388 } | 3388 } |
3389 | 3389 |
3390 bool Extension::CanExecuteScriptOnPage(const GURL& page_url, | 3390 bool Extension::CanExecuteScriptOnPage(const GURL& page_url, |
3391 int tab_id, | |
3391 const UserScript* script, | 3392 const UserScript* script, |
3392 std::string* error) const { | 3393 std::string* error) const { |
3393 base::AutoLock auto_lock(runtime_data_lock_); | 3394 base::AutoLock auto_lock(runtime_data_lock_); |
3394 // The gallery is special-cased as a restricted URL for scripting to prevent | 3395 // The gallery is special-cased as a restricted URL for scripting to prevent |
3395 // access to special JS bindings we expose to the gallery (and avoid things | 3396 // access to special JS bindings we expose to the gallery (and avoid things |
3396 // like extensions removing the "report abuse" link). | 3397 // like extensions removing the "report abuse" link). |
3397 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing | 3398 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing |
3398 // against the store app extent? | 3399 // against the store app extent? |
3399 GURL store_url(extension_urls::GetWebstoreLaunchURL()); | 3400 GURL store_url(extension_urls::GetWebstoreLaunchURL()); |
3400 if ((page_url.host() == store_url.host()) && | 3401 if ((page_url.host() == store_url.host()) && |
3401 !CanExecuteScriptEverywhere() && | 3402 !CanExecuteScriptEverywhere() && |
3402 !CommandLine::ForCurrentProcess()->HasSwitch( | 3403 !CommandLine::ForCurrentProcess()->HasSwitch( |
3403 switches::kAllowScriptingGallery)) { | 3404 switches::kAllowScriptingGallery)) { |
3404 if (error) | 3405 if (error) |
3405 *error = errors::kCannotScriptGallery; | 3406 *error = errors::kCannotScriptGallery; |
3406 return false; | 3407 return false; |
3407 } | 3408 } |
3408 | 3409 |
3409 if (page_url.SchemeIs(chrome::kChromeUIScheme) && | 3410 if (page_url.SchemeIs(chrome::kChromeUIScheme) && |
3410 !CanExecuteScriptEverywhere()) | 3411 !CanExecuteScriptEverywhere()) |
3411 return false; | 3412 return false; |
3412 | 3413 |
3414 // If a tab ID is specified, try the tab-specific permissions. | |
3415 if (tab_id >= 0) { | |
3416 const URLPatternSet* tab_permissions = | |
3417 runtime_data_.GetTabSpecificHostPermissions(tab_id); | |
3418 if (tab_permissions && | |
3419 tab_permissions->MatchesSecurityOrigin(page_url)) { | |
3420 return true; | |
3421 } | |
3422 } | |
3423 | |
3413 // If a script is specified, use its matches. | 3424 // If a script is specified, use its matches. |
3414 if (script) | 3425 if (script) |
3415 return script->MatchesURL(page_url); | 3426 return script->MatchesURL(page_url); |
3416 | 3427 |
3417 // Otherwise, see if this extension has permission to execute script | 3428 // Otherwise, see if this extension has permission to execute script |
3418 // programmatically on pages. | 3429 // programmatically on pages. |
3419 if (runtime_data_.GetActivePermissions()->HasExplicitAccessToOrigin( | 3430 if (runtime_data_.GetActivePermissions()->HasExplicitAccessToOrigin( |
3420 page_url)) | 3431 page_url)) |
3421 return true; | 3432 return true; |
3422 | 3433 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3465 it != whitelist->end(); ++it) { | 3476 it != whitelist->end(); ++it) { |
3466 if (id() == *it) { | 3477 if (id() == *it) { |
3467 return true; | 3478 return true; |
3468 } | 3479 } |
3469 } | 3480 } |
3470 | 3481 |
3471 return false; | 3482 return false; |
3472 } | 3483 } |
3473 | 3484 |
3474 bool Extension::CanCaptureVisiblePage(const GURL& page_url, | 3485 bool Extension::CanCaptureVisiblePage(const GURL& page_url, |
3486 int tab_id, | |
3475 std::string *error) const { | 3487 std::string *error) const { |
3488 if (tab_id >= 0) { | |
3489 const URLPatternSet* tab = GetTabSpecificHostPermissions(tab_id); | |
3490 if (tab && tab->MatchesSecurityOrigin(page_url)) | |
3491 return true; | |
3492 } | |
3493 | |
3476 if (HasHostPermission(page_url) || page_url.GetOrigin() == url()) | 3494 if (HasHostPermission(page_url) || page_url.GetOrigin() == url()) |
3477 return true; | 3495 return true; |
3478 | 3496 |
3479 if (error) { | 3497 if (error) { |
3480 *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, | 3498 *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, |
3481 page_url.spec()); | 3499 page_url.spec()); |
3482 } | 3500 } |
3483 return false; | 3501 return false; |
3484 } | 3502 } |
3485 | 3503 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3641 script_badge_->SetIcon(kDefaultTabId, icon); | 3659 script_badge_->SetIcon(kDefaultTabId, icon); |
3642 | 3660 |
3643 std::string title = browser_action()->GetTitle(kDefaultTabId); | 3661 std::string title = browser_action()->GetTitle(kDefaultTabId); |
3644 if (!title.empty()) | 3662 if (!title.empty()) |
3645 script_badge_->SetTitle(kDefaultTabId, title); | 3663 script_badge_->SetTitle(kDefaultTabId, title); |
3646 } | 3664 } |
3647 | 3665 |
3648 return script_badge_.get(); | 3666 return script_badge_.get(); |
3649 } | 3667 } |
3650 | 3668 |
3669 const URLPatternSet* Extension::GetTabSpecificHostPermissions( | |
3670 int tab_id) const { | |
3671 base::AutoLock auto_lock(runtime_data_lock_); | |
3672 return runtime_data_.GetTabSpecificHostPermissions(tab_id); | |
3673 } | |
3674 | |
3675 void Extension::SetTabSpecificHostPermissions( | |
3676 int tab_id, | |
3677 const URLPatternSet& permissions) const { | |
3678 base::AutoLock auto_lock(runtime_data_lock_); | |
3679 runtime_data_.SetTabSpecificHostPermissions(tab_id, permissions); | |
3680 } | |
3681 | |
3682 void Extension::ClearTabSpecificHostPermissions(int tab_id) const { | |
3683 base::AutoLock auto_lock(runtime_data_lock_); | |
3684 runtime_data_.ClearTabSpecificHostPermissions(tab_id); | |
3685 } | |
3686 | |
3687 const URLPatternSet* Extension::GetActiveHostPermissionsForAllTabs() const { | |
3688 base::AutoLock auto_lock(runtime_data_lock_); | |
3689 return runtime_data_.GetActiveHostPermissionsForAllTabs(); | |
3690 } | |
3691 | |
3692 void Extension::GetAllTabSpecificHostPermissions( | |
3693 std::map<int, URLPatternSet>* out) const { | |
3694 base::AutoLock auto_lock(runtime_data_lock_); | |
3695 runtime_data_.GetAllTabSpecificHostPermissions(out); | |
3696 } | |
3697 | |
3698 void Extension::SetAllTabSpecificHostPermissions( | |
3699 const std::map<int, URLPatternSet>& origins) const { | |
3700 base::AutoLock auto_lock(runtime_data_lock_); | |
3701 runtime_data_.SetAllTabSpecificHostPermissions(origins); | |
3702 } | |
3703 | |
3651 bool Extension::CheckPlatformAppFeatures(std::string* utf8_error) { | 3704 bool Extension::CheckPlatformAppFeatures(std::string* utf8_error) { |
3652 if (!is_platform_app()) | 3705 if (!is_platform_app()) |
3653 return true; | 3706 return true; |
3654 | 3707 |
3655 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 3708 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
3656 switches::kEnablePlatformApps)) { | 3709 switches::kEnablePlatformApps)) { |
3657 *utf8_error = errors::kPlatformAppFlagRequired; | 3710 *utf8_error = errors::kPlatformAppFlagRequired; |
3658 return false; | 3711 return false; |
3659 } | 3712 } |
3660 | 3713 |
(...skipping 23 matching lines...) Expand all Loading... | |
3684 Extension::RuntimeData::~RuntimeData() {} | 3737 Extension::RuntimeData::~RuntimeData() {} |
3685 | 3738 |
3686 scoped_refptr<const ExtensionPermissionSet> | 3739 scoped_refptr<const ExtensionPermissionSet> |
3687 Extension::RuntimeData::GetActivePermissions() const { | 3740 Extension::RuntimeData::GetActivePermissions() const { |
3688 return active_permissions_; | 3741 return active_permissions_; |
3689 } | 3742 } |
3690 | 3743 |
3691 void Extension::RuntimeData::SetActivePermissions( | 3744 void Extension::RuntimeData::SetActivePermissions( |
3692 const ExtensionPermissionSet* active) { | 3745 const ExtensionPermissionSet* active) { |
3693 active_permissions_ = active; | 3746 active_permissions_ = active; |
3747 active_host_permissions_for_all_tabs_.reset(); | |
3748 } | |
3749 | |
3750 const URLPatternSet* | |
3751 Extension::RuntimeData::GetTabSpecificHostPermissions(int tab_id) const { | |
3752 CHECK_GE(tab_id, 0); | |
3753 TabHostPermissionsMap::const_iterator it = | |
3754 tab_specific_host_permissions_.find(tab_id); | |
3755 return (it != tab_specific_host_permissions_.end()) ? it->second.get() : NULL; | |
3756 } | |
3757 | |
3758 void Extension::RuntimeData::SetTabSpecificHostPermissions( | |
3759 int tab_id, | |
3760 const URLPatternSet& hosts) { | |
3761 CHECK_GE(tab_id, 0); | |
3762 tab_specific_host_permissions_[tab_id] = | |
3763 make_linked_ptr(new URLPatternSet(hosts)); | |
3764 | |
3765 // If we're tracking the active host permissions for all tabs, update it. | |
3766 if (active_host_permissions_for_all_tabs_.get()) { | |
3767 scoped_ptr<URLPatternSet> updated(new URLPatternSet()); | |
3768 URLPatternSet::CreateUnion(*active_host_permissions_for_all_tabs_, | |
3769 hosts, | |
3770 updated.get()); | |
3771 active_host_permissions_for_all_tabs_ = updated.Pass(); | |
3772 } | |
3773 } | |
3774 | |
3775 void Extension::RuntimeData::ClearTabSpecificHostPermissions(int tab_id) { | |
3776 CHECK_GE(tab_id, 0); | |
3777 tab_specific_host_permissions_.erase(tab_id); | |
3778 active_host_permissions_for_all_tabs_.reset(); | |
3779 } | |
3780 | |
3781 const URLPatternSet* | |
3782 Extension::RuntimeData::GetActiveHostPermissionsForAllTabs() const { | |
3783 if (active_host_permissions_for_all_tabs_.get()) | |
3784 return active_host_permissions_for_all_tabs_.get(); | |
3785 | |
3786 if (tab_specific_host_permissions_.empty()) | |
3787 return &active_permissions_->explicit_hosts(); | |
3788 | |
3789 // Compute and cache the union of all tab specific permissions. The union | |
3790 // operation for ExtensionPermissionSet is O(n), so the naive union | |
3791 // implementation would be O(n^2). Try to be smarter and do it in O(nlog(n)). | |
3792 std::vector<linked_ptr<const URLPatternSet> > all; | |
Aaron Boodman
2012/06/08 05:31:30
Consider moving this into a method of URLPatternSe
not at google - send to devlin
2012/06/12 20:40:51
Done.
| |
3793 for (TabHostPermissionsMap::const_iterator it = | |
3794 tab_specific_host_permissions_.begin(); | |
3795 it != tab_specific_host_permissions_.end(); ++it) { | |
3796 all.push_back(it->second); | |
3797 } | |
3798 | |
3799 for (size_t skip = 1; skip < all.size(); skip *= 2) { | |
3800 for (size_t i = 0; i < all.size() - skip; i += skip) { | |
Aaron Boodman
2012/06/08 05:31:30
(all.size() - skip) for clarity.
not at google - send to devlin
2012/06/12 20:40:51
ok.
| |
3801 URLPatternSet* u = new URLPatternSet(); | |
3802 URLPatternSet::CreateUnion(*all[i], *all[i + skip], u); | |
3803 all[i] = make_linked_ptr(u); | |
3804 } | |
3805 } | |
3806 | |
3807 active_host_permissions_for_all_tabs_.reset(new URLPatternSet()); | |
3808 URLPatternSet::CreateUnion( | |
3809 *all[0], | |
3810 active_permissions_->explicit_hosts(), | |
3811 active_host_permissions_for_all_tabs_.get()); | |
3812 return active_host_permissions_for_all_tabs_.get(); | |
3813 } | |
3814 | |
3815 void Extension::RuntimeData::GetAllTabSpecificHostPermissions( | |
3816 std::map<int, URLPatternSet>* out) const { | |
3817 for (TabHostPermissionsMap::const_iterator it = | |
3818 tab_specific_host_permissions_.begin(); | |
3819 it != tab_specific_host_permissions_.end(); ++it) { | |
3820 (*out)[it->first] = *it->second; | |
Aaron Boodman
2012/06/08 05:31:30
You aren't saving much by passing an out param bec
not at google - send to devlin
2012/06/12 20:40:51
Done.
| |
3821 } | |
3822 } | |
3823 | |
3824 void Extension::RuntimeData::SetAllTabSpecificHostPermissions( | |
3825 const std::map<int, URLPatternSet>& in) { | |
3826 tab_specific_host_permissions_.clear(); | |
3827 active_host_permissions_for_all_tabs_.reset(); | |
3828 | |
3829 for (std::map<int, URLPatternSet>::const_iterator it = in.begin(); | |
3830 it != in.end(); ++it) { | |
3831 tab_specific_host_permissions_[it->first].reset( | |
3832 new URLPatternSet(it->second)); | |
3833 } | |
3694 } | 3834 } |
3695 | 3835 |
3696 UnloadedExtensionInfo::UnloadedExtensionInfo( | 3836 UnloadedExtensionInfo::UnloadedExtensionInfo( |
3697 const Extension* extension, | 3837 const Extension* extension, |
3698 extension_misc::UnloadedExtensionReason reason) | 3838 extension_misc::UnloadedExtensionReason reason) |
3699 : reason(reason), | 3839 : reason(reason), |
3700 already_disabled(false), | 3840 already_disabled(false), |
3701 extension(extension) {} | 3841 extension(extension) {} |
3702 | 3842 |
3703 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3843 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
3704 const Extension* extension, | 3844 const Extension* extension, |
3705 const ExtensionPermissionSet* permissions, | 3845 const ExtensionPermissionSet* permissions, |
3706 Reason reason) | 3846 Reason reason) |
3707 : reason(reason), | 3847 : reason(reason), |
3708 extension(extension), | 3848 extension(extension), |
3709 permissions(permissions) {} | 3849 permissions(permissions) {} |
3710 | 3850 |
3711 } // namespace extensions | 3851 } // namespace extensions |
OLD | NEW |