Chromium Code Reviews| 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 |