diff options
31 files changed, 112 insertions, 283 deletions
diff --git a/chrome/browser/browser_url_handler.cc b/chrome/browser/browser_url_handler.cc index 6707606..b209e04 100644 --- a/chrome/browser/browser_url_handler.cc +++ b/chrome/browser/browser_url_handler.cc @@ -60,7 +60,7 @@ static bool ReverseViewSource(GURL* url, Profile* profile) { // Handles rewriting DOM UI URLs. static bool HandleDOMUI(GURL* url, Profile* profile) { - if (!DOMUIFactory::UseDOMUIForURL(profile, *url)) + if (!DOMUIFactory::UseDOMUIForURL(*url)) return false; // Special case the new tab page. In older versions of Chrome, the new tab diff --git a/chrome/browser/dom_ui/dom_ui_factory.cc b/chrome/browser/dom_ui/dom_ui_factory.cc index c53e652..251f646 100644 --- a/chrome/browser/dom_ui/dom_ui_factory.cc +++ b/chrome/browser/dom_ui/dom_ui_factory.cc @@ -55,14 +55,14 @@ DOMUI* NewDOMUI(TabContents* contents, const GURL& url) { // Special case for extensions. template<> DOMUI* NewDOMUI<ExtensionDOMUI>(TabContents* contents, const GURL& url) { - // Don't use a DOMUI for incognito tabs because we require extensions to run - // within a single process. + // Don't use a DOMUI for non-existent extensions or for incognito tabs. The + // latter restriction is because we require extensions to run within a single + // process. ExtensionsService* service = contents->profile()->GetExtensionsService(); - if (service && - service->ExtensionBindingsAllowed(url) && - !contents->profile()->IsOffTheRecord()) { + bool valid_extension = + (service && service->GetExtensionById(url.host(), false)); + if (valid_extension && !contents->profile()->IsOffTheRecord()) return new ExtensionDOMUI(contents); - } return NULL; } @@ -70,14 +70,12 @@ DOMUI* NewDOMUI<ExtensionDOMUI>(TabContents* contents, const GURL& url) { // tab, based on its URL. Returns NULL if the URL doesn't have DOMUI associated // with it. Even if the factory function is valid, it may yield a NULL DOMUI // when invoked for a particular tab - see NewDOMUI<ExtensionDOMUI>. -static DOMUIFactoryFunction GetDOMUIFactoryFunction(Profile* profile, - const GURL& url) { +static DOMUIFactoryFunction GetDOMUIFactoryFunction(const GURL& url) { // Currently, any gears: URL means an HTML dialog. if (url.SchemeIs(chrome::kGearsScheme)) return &NewDOMUI<HtmlDialogUI>; - ExtensionsService* service = profile->GetExtensionsService(); - if (service && service->ExtensionBindingsAllowed(url)) + if (url.SchemeIs(chrome::kExtensionScheme)) return &NewDOMUI<ExtensionDOMUI>; // All platform builds of Chrome will need to have a cloud printing @@ -161,8 +159,8 @@ static DOMUIFactoryFunction GetDOMUIFactoryFunction(Profile* profile, } // static -DOMUITypeID DOMUIFactory::GetDOMUIType(Profile* profile, const GURL& url) { - DOMUIFactoryFunction function = GetDOMUIFactoryFunction(profile, url); +DOMUITypeID DOMUIFactory::GetDOMUIType(const GURL& url) { + DOMUIFactoryFunction function = GetDOMUIFactoryFunction(url); return function ? reinterpret_cast<DOMUITypeID>(function) : kNoDOMUI; } @@ -174,15 +172,14 @@ bool DOMUIFactory::HasDOMUIScheme(const GURL& url) { } // static -bool DOMUIFactory::UseDOMUIForURL(Profile* profile, const GURL& url) { - return GetDOMUIFactoryFunction(profile, url) != NULL; +bool DOMUIFactory::UseDOMUIForURL(const GURL& url) { + return GetDOMUIFactoryFunction(url) != NULL; } // static DOMUI* DOMUIFactory::CreateDOMUIForURL(TabContents* tab_contents, const GURL& url) { - DOMUIFactoryFunction function = GetDOMUIFactoryFunction( - tab_contents->profile(), url); + DOMUIFactoryFunction function = GetDOMUIFactoryFunction(url); if (!function) return NULL; return (*function)(tab_contents, url); diff --git a/chrome/browser/dom_ui/dom_ui_factory.h b/chrome/browser/dom_ui/dom_ui_factory.h index 3a7bfc6..ba8dabe 100644 --- a/chrome/browser/dom_ui/dom_ui_factory.h +++ b/chrome/browser/dom_ui/dom_ui_factory.h @@ -27,7 +27,7 @@ class DOMUIFactory { // Returns a type identifier indicating what DOMUI we would use for the // given URL. This is useful for comparing the potential DOMUIs for two URLs. // Returns kNoDOMUI if the given URL will not use the DOM UI system. - static DOMUITypeID GetDOMUIType(Profile* profile, const GURL& url); + static DOMUITypeID GetDOMUIType(const GURL& url); // Returns true if the given URL's scheme would trigger the DOM UI system. // This is a less precise test than UseDONUIForURL, which tells you whether @@ -36,7 +36,7 @@ class DOMUIFactory { static bool HasDOMUIScheme(const GURL& url); // Returns true if the given URL will use the DOM UI system. - static bool UseDOMUIForURL(Profile* profile, const GURL& url); + static bool UseDOMUIForURL(const GURL& url); // Allocates a new DOMUI object for the given URL, and returns it. If the URL // is not a DOM UI URL, then it will return NULL. When non-NULL, ownership of diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc index 689a88c..1ca01cc 100644 --- a/chrome/browser/extensions/app_process_apitest.cc +++ b/chrome/browser/extensions/app_process_apitest.cc @@ -86,9 +86,10 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcess) { // The extension should have opened 3 new tabs. Including the original blank // tab, we now have 4 tabs. Two should be part of the extension app, and - // grouped in the same process. + // grouped in the extension process. ASSERT_EQ(4, browser()->tab_count()); RenderViewHost* host = browser()->GetTabContentsAt(1)->render_view_host(); + EXPECT_TRUE(host->is_extension_process()); EXPECT_EQ(host->process(), browser()->GetTabContentsAt(2)->render_view_host()->process()); diff --git a/chrome/browser/extensions/content_script_all_frames_apitest.cc b/chrome/browser/extensions/content_script_all_frames_apitest.cc index 3ed2f05..fac6362 100644 --- a/chrome/browser/extensions/content_script_all_frames_apitest.cc +++ b/chrome/browser/extensions/content_script_all_frames_apitest.cc @@ -9,10 +9,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptAllFrames) { ASSERT_TRUE(RunExtensionTest("content_scripts/all_frames")) << message_; } -// TODO(rafaelw): This test now fails because non-extension processes do not -// get extension bindings setup by scheme. Fixing crbug.com/53610 will fix this. -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, - DISABLED_ContentScriptExtensionIframe) { +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptExtensionIframe) { ASSERT_TRUE(test_server()->Start()); ASSERT_TRUE(RunExtensionTest("content_scripts/extension_iframe")) << message_; } diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index a8253cf..51cc8fe 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -333,13 +333,7 @@ ExtensionFunctionDispatcher* ExtensionFunctionDispatcher::Create( render_view_host->process()->profile()->GetExtensionsService(); DCHECK(service); - if (!service->ExtensionBindingsAllowed(url)) - return NULL; - Extension* extension = service->GetExtensionByURL(url); - if (!extension) - extension = service->GetExtensionByWebExtent(url); - if (extension) return new ExtensionFunctionDispatcher(render_view_host, delegate, extension, url); @@ -356,12 +350,10 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( render_view_host_(render_view_host), delegate_(delegate), url_(url), - extension_id_(extension->id()), ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) { // TODO(erikkay) should we do something for these errors in Release? + DCHECK(url.SchemeIs(chrome::kExtensionScheme)); DCHECK(extension); - DCHECK(url.SchemeIs(chrome::kExtensionScheme) || - extension->location() == Extension::COMPONENT); // Notify the ExtensionProcessManager that the view was created. ExtensionProcessManager* epm = profile()->GetExtensionProcessManager(); @@ -456,17 +448,6 @@ void ExtensionFunctionDispatcher::HandleRequest( DCHECK(extension); function->set_include_incognito(service->IsIncognitoEnabled(extension)); - std::string permission_name = function->name(); - size_t separator = permission_name.find_first_of("./"); - if (separator != std::string::npos) - permission_name = permission_name.substr(0, separator); - - if (!service->ExtensionBindingsAllowed(function->source_url()) || - !extension->HasApiPermission(permission_name)) { - render_view_host_->BlockExtensionRequest(function->request_id()); - return; - } - ExtensionsQuotaService* quota = service->quota_service(); if (quota->Assess(extension_id(), function, ¶ms.arguments, base::TimeTicks::Now())) { diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h index 2e8251f..9bddecf 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.h +++ b/chrome/browser/extensions/extension_function_dispatcher.h @@ -114,7 +114,7 @@ class ExtensionFunctionDispatcher { const GURL& url() { return url_; } // Gets the ID for this extension. - const std::string extension_id() { return extension_id_; } + const std::string extension_id() { return url_.host(); } // The profile that this dispatcher is associated with. Profile* profile(); @@ -139,8 +139,6 @@ class ExtensionFunctionDispatcher { GURL url_; - std::string extension_id_; - scoped_refptr<Peer> peer_; // AutomationExtensionFunction requires access to the RenderViewHost diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index f43501b..1c1a675 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -513,8 +513,7 @@ void ExtensionHost::CreateNewWindow( route_id, render_view_host()->process()->profile(), site_instance(), - DOMUIFactory::GetDOMUIType(render_view_host()->process()->profile(), - url_), + DOMUIFactory::GetDOMUIType(url_), this, window_container_type, frame_name); diff --git a/chrome/browser/extensions/extension_messages_browsertest.cc b/chrome/browser/extensions/extension_messages_browsertest.cc index 5e78c79..3b3c273 100644 --- a/chrome/browser/extensions/extension_messages_browsertest.cc +++ b/chrome/browser/extensions/extension_messages_browsertest.cc @@ -16,11 +16,8 @@ static void DispatchOnConnect(int source_port_id, const std::string& name, args.Set(0, Value::CreateIntegerValue(source_port_id)); args.Set(1, Value::CreateStringValue(name)); args.Set(2, Value::CreateStringValue(tab_json)); - // Testing extensionId. Set in EventBindings::HandleContextCreated. - // We use the same id for source & target to similute an extension "talking - // to itself". - args.Set(3, Value::CreateStringValue(EventBindings::kTestingExtensionId)); - args.Set(4, Value::CreateStringValue(EventBindings::kTestingExtensionId)); + args.Set(3, Value::CreateStringValue("")); // extension ID is empty for tests + args.Set(4, Value::CreateStringValue("")); // extension ID is empty for tests RendererExtensionBindings::Invoke( ExtensionMessageService::kDispatchOnConnect, args, NULL, false, GURL()); } diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 815ee49..3fb4a91 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -533,7 +533,7 @@ void ExtensionsService::LoadComponentExtensions() { // In order for the --apps-gallery-url switch to work with the gallery // process isolation, we must insert any provided value into the component // app's launch url and web extent. - if (extension->id() == extension_misc::kWebStoreAppId) { + if (extension->id() == extension_misc::kWebStoreAppId ) { GURL gallery_url(CommandLine::ForCurrentProcess() ->GetSwitchValueASCII(switches::kAppsGalleryURL)); if (gallery_url.is_valid()) { @@ -1255,16 +1255,6 @@ Extension* ExtensionsService::GetExtensionByWebExtent(const GURL& url) { return NULL; } -bool ExtensionsService::ExtensionBindingsAllowed(const GURL& url) { - // Allow bindings for all packaged extension. - if (GetExtensionByURL(url)) - return true; - - // Allow bindings for all component, hosted apps. - Extension* extension = GetExtensionByWebExtent(url); - return (extension && extension->location() == Extension::COMPONENT); -} - Extension* ExtensionsService::GetExtensionByOverlappingWebExtent( const ExtensionExtent& extent) { for (size_t i = 0; i < extensions_.size(); ++i) { diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index efdc17b..45110d4 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -288,11 +288,6 @@ class ExtensionsService // extent, if one exists. Extension* GetExtensionByOverlappingWebExtent(const ExtensionExtent& extent); - // Returns true if |url| should get extension api bindings and be permitted - // to make api calls. Note that this is independent of what extension - // permissions the given extension has been granted. - bool ExtensionBindingsAllowed(const GURL& url); - // Returns the icon to display in the omnibox for the given extension. const SkBitmap& GetOmniboxIcon(const std::string& extension_id); diff --git a/chrome/browser/notifications/balloon_host.cc b/chrome/browser/notifications/balloon_host.cc index 8e5b676..9e8f379 100644 --- a/chrome/browser/notifications/balloon_host.cc +++ b/chrome/browser/notifications/balloon_host.cc @@ -94,8 +94,7 @@ void BalloonHost::CreateNewWindow( route_id, balloon_->profile(), site_instance_.get(), - DOMUIFactory::GetDOMUIType(balloon_->profile(), - balloon_->notification().content_url()), + DOMUIFactory::GetDOMUIType(balloon_->notification().content_url()), this, window_container_type, frame_name); diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index b160a1f..b4727c7 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -670,7 +670,6 @@ void BrowserRenderProcessHost::SendExtensionInfo() { info.id = extension->id(); info.web_extent = extension->web_extent(); info.name = extension->name(); - info.location = extension->location(); info.icon_url = extension->GetIconUrlAllowLargerSize(Extension::EXTENSION_ICON_MEDIUM); params.extensions.push_back(info); diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index c31301b..6dad785 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -732,7 +732,7 @@ class RenderViewHost : public RenderWidgetHost { // The session storage namespace id to be used by the associated render view. int64 session_storage_namespace_id_; - // Whether this render view will get extension api bindings. This controls + // Whether this render view will be used for extensions. This controls // what process type we use. bool is_extension_process_; diff --git a/chrome/browser/tab_contents/background_contents.cc b/chrome/browser/tab_contents/background_contents.cc index b33ae32..7b35bdc 100644 --- a/chrome/browser/tab_contents/background_contents.cc +++ b/chrome/browser/tab_contents/background_contents.cc @@ -166,14 +166,13 @@ void BackgroundContents::CreateNewWindow( int route_id, WindowContainerType window_container_type, const string16& frame_name) { - delegate_view_helper_.CreateNewWindow( - route_id, - render_view_host_->process()->profile(), - render_view_host_->site_instance(), - DOMUIFactory::GetDOMUIType(render_view_host_->process()->profile(), url_), - this, - window_container_type, - frame_name); + delegate_view_helper_.CreateNewWindow(route_id, + render_view_host_->process()->profile(), + render_view_host_->site_instance(), + DOMUIFactory::GetDOMUIType(url_), + this, + window_container_type, + frame_name); } void BackgroundContents::CreateNewWidget(int route_id, diff --git a/chrome/browser/tab_contents/render_view_host_manager.cc b/chrome/browser/tab_contents/render_view_host_manager.cc index d30b7d3..e5f7426 100644 --- a/chrome/browser/tab_contents/render_view_host_manager.cc +++ b/chrome/browser/tab_contents/render_view_host_manager.cc @@ -309,9 +309,8 @@ bool RenderViewHostManager::ShouldSwapProcessesForNavigation( // For security, we should transition between processes when one is a DOM UI // page and one isn't. - Profile* profile = delegate_->GetControllerForRenderManager().profile(); - if (DOMUIFactory::UseDOMUIForURL(profile, cur_entry->url()) != - DOMUIFactory::UseDOMUIForURL(profile, new_entry->url())) + if (DOMUIFactory::UseDOMUIForURL(cur_entry->url()) != + DOMUIFactory::UseDOMUIForURL(new_entry->url())) return true; // Also, we must switch if one is an extension and the other is not the exact @@ -473,8 +472,14 @@ bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, // Tell the RenderView whether it will be used for an extension process. Profile* profile = delegate_->GetControllerForRenderManager().profile(); - bool is_extension_process = profile->GetExtensionsService() && - profile->GetExtensionsService()->ExtensionBindingsAllowed(entry.url()); + bool is_extension_process = false; + if (entry.url().SchemeIs(chrome::kExtensionScheme)) { + is_extension_process = true; + } else if (profile->GetExtensionsService() && + profile->GetExtensionsService()-> + GetExtensionByWebExtent(entry.url())) { + is_extension_process = true; + } render_view_host->set_is_extension_process(is_extension_process); return delegate_->CreateRenderViewForRenderManager(render_view_host); diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index e6bbe98..a21ea8f 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -857,7 +857,7 @@ bool TabContents::NavigateToPendingEntry( // to a DOM UI renderer. Double check that here. int enabled_bindings = dest_render_view_host->enabled_bindings(); bool is_allowed_in_dom_ui_renderer = - DOMUIFactory::UseDOMUIForURL(profile(), entry.url()) || + DOMUIFactory::UseDOMUIForURL(entry.url()) || entry.url() == GURL(chrome::kAboutBlankURL); CHECK(!BindingsPolicy::is_dom_ui_enabled(enabled_bindings) || is_allowed_in_dom_ui_renderer); @@ -1603,8 +1603,7 @@ void TabContents::DidNavigateMainFramePostCommit( // If this is a window.open navigation, use the same DOMUI as the renderer // that opened the window, as long as both renderers have the same // privileges. - if (opener_dom_ui_type_ == - DOMUIFactory::GetDOMUIType(profile(), GetURL())) { + if (opener_dom_ui_type_ == DOMUIFactory::GetDOMUIType(GetURL())) { DOMUI* dom_ui = DOMUIFactory::CreateDOMUIForURL(this, GetURL()); // dom_ui might be NULL if the URL refers to a non-existent extension. if (dom_ui) { diff --git a/chrome/browser/tab_contents/tab_contents_view.cc b/chrome/browser/tab_contents/tab_contents_view.cc index dd0242eb..9c369d0 100644 --- a/chrome/browser/tab_contents/tab_contents_view.cc +++ b/chrome/browser/tab_contents/tab_contents_view.cc @@ -34,8 +34,7 @@ void TabContentsView::CreateNewWindow( route_id, tab_contents_->profile(), tab_contents_->GetSiteInstance(), - DOMUIFactory::GetDOMUIType(tab_contents_->profile(), - tab_contents_->GetURL()), + DOMUIFactory::GetDOMUIType(tab_contents_->GetURL()), tab_contents_, window_container_type, frame_name); diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index f8862e3..728006c 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -93,29 +93,6 @@ bool IsBaseCrxKey(const std::string& key) { return false; } -// Names of API modules that do not require a permission. -const char kBrowserActionModuleName[] = "browserAction"; -const char kBrowserActionsModuleName[] = "browserActions"; -const char kDevToolsModuleName[] = "devtools"; -const char kExtensionModuleName[] = "extension"; -const char kI18NModuleName[] = "i18n"; -const char kPageActionModuleName[] = "pageAction"; -const char kPageActionsModuleName[] = "pageActions"; -const char kTestModuleName[] = "test"; - -const char* kNonPermissionModuleNames[] = { - kBrowserActionModuleName, - kBrowserActionsModuleName, - kDevToolsModuleName, - kExtensionModuleName, - kI18NModuleName, - kPageActionModuleName, - kPageActionsModuleName, - kTestModuleName -}; -const size_t kNumNonPermissionModuleNames = - arraysize(kNonPermissionModuleNames); - } // namespace const FilePath::CharType Extension::kManifestFilename[] = @@ -146,7 +123,6 @@ const int Extension::kIconSizes[] = { const int Extension::kPageActionIconMaxSize = 19; const int Extension::kBrowserActionIconMaxSize = 19; -// Explicit permissions -- permission declaration required. const char* Extension::kBackgroundPermission = "background"; const char* Extension::kContextMenusPermission = "contextMenus"; const char* Extension::kBookmarkPermission = "bookmarks"; @@ -1746,29 +1722,6 @@ bool Extension::CanAccessURL(const URLPattern pattern) const { return true; } -// static. -bool Extension::HasApiPermission( - const std::vector<std::string>& api_permissions, - const std::string& permission) { - std::string permission_name = permission; - - // windows and tabs are the same permission. - if (permission_name == "windows") - permission_name = Extension::kTabPermission; - - if (std::find(api_permissions.begin(), api_permissions.end(), - permission_name) != api_permissions.end()) - return true; - - for (size_t i = 0; i < kNumNonPermissionModuleNames; ++i) { - if (permission_name == kNonPermissionModuleNames[i]) { - return true; - } - } - - return false; -} - bool Extension::HasHostPermission(const GURL& url) const { for (URLPatternList::const_iterator host = host_permissions_.begin(); host != host_permissions_.end(); ++host) { diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index c94b18c..e9a25cc 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -272,11 +272,9 @@ class Extension { } // Returns true if the extension has the specified API permission. - static bool HasApiPermission(const std::vector<std::string>& api_permissions, - const std::string& permission); - bool HasApiPermission(const std::string& permission) const { - return HasApiPermission(this->api_permissions(), permission); + return std::find(api_permissions_.begin(), api_permissions_.end(), + permission) != api_permissions_.end(); } // Returns the set of hosts that the extension effectively has access to. This diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc index 5e18590..5ad995e 100644 --- a/chrome/common/render_messages_params.cc +++ b/chrome/common/render_messages_params.cc @@ -212,28 +212,6 @@ struct ParamTraits<WindowContainerType> { } }; -template <> -struct ParamTraits<Extension::Location> { - typedef Extension::Location param_type; - static void Write(Message* m, const param_type& p) { - int val = static_cast<int>(p); - WriteParam(m, val); - } - static bool Read(const Message* m, void** iter, param_type* p) { - int val = 0; - if (!ReadParam(m, iter, &val) || - val < Extension::INVALID || - val >= Extension::EXTERNAL_PREF_DOWNLOAD) - return false; - *p = static_cast<param_type>(val); - return true; - } - static void Log(const param_type& p, std::string* l) { - ParamTraits<int>::Log(static_cast<int>(p), l); - } -}; - - void ParamTraits<ViewMsg_Navigate_Params>::Write(Message* m, const param_type& p) { WriteParam(m, p.page_id); @@ -1291,7 +1269,6 @@ void ParamTraits<ViewMsg_ExtensionRendererInfo>::Write(Message* m, WriteParam(m, p.web_extent); WriteParam(m, p.name); WriteParam(m, p.icon_url); - WriteParam(m, p.location); } bool ParamTraits<ViewMsg_ExtensionRendererInfo>::Read(const Message* m, @@ -1300,8 +1277,7 @@ bool ParamTraits<ViewMsg_ExtensionRendererInfo>::Read(const Message* m, return ReadParam(m, iter, &p->id) && ReadParam(m, iter, &p->web_extent) && ReadParam(m, iter, &p->name) && - ReadParam(m, iter, &p->icon_url) && - ReadParam(m, iter, &p->location); + ReadParam(m, iter, &p->icon_url); } void ParamTraits<ViewMsg_ExtensionRendererInfo>::Log(const param_type& p, diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h index 5666ae1..141e7f9 100644 --- a/chrome/common/render_messages_params.h +++ b/chrome/common/render_messages_params.h @@ -16,7 +16,6 @@ #include "base/time.h" #include "base/values.h" #include "chrome/common/dom_storage_common.h" -#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_extent.h" #include "chrome/common/extensions/url_pattern.h" #include "chrome/common/indexed_db_key.h" @@ -791,7 +790,6 @@ struct ViewMsg_ExtensionRendererInfo { ExtensionExtent web_extent; std::string name; GURL icon_url; - Extension::Location location; }; struct ViewMsg_ExtensionsUpdated_Params { diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc index 24a84cb..52f5d0e 100644 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -11,7 +11,6 @@ #include "chrome/renderer/extensions/bindings_utils.h" #include "chrome/renderer/extensions/event_bindings.h" #include "chrome/renderer/extensions/extension_process_bindings.h" -#include "chrome/renderer/extensions/extension_renderer_info.h" #include "chrome/renderer/extensions/js_only_v8_extensions.h" #include "chrome/renderer/render_thread.h" #include "chrome/renderer/render_view.h" @@ -168,8 +167,6 @@ static bool HasSufficientPermissions(ContextInfo* context, } // namespace const char* EventBindings::kName = "chrome/EventBindings"; -const char* EventBindings::kTestingExtensionId = - "oooooooooooooooooooooooooooooooo"; v8::Extension* EventBindings::Get() { static v8::Extension* extension = new ExtensionImpl(); @@ -260,16 +257,10 @@ void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) { if (!ds) ds = frame->dataSource(); GURL url = ds->request().url(); - std::string extension_id = ExtensionRendererInfo::GetIdByURL(url); - - // Note: because process isolation doesn't work correcly with redirects, - // it is possible that a page that IS in an extension process won't have - // bindings setup for it, so we must also check IsExtensionProcess, otherwise - // we'll attempt to invoke a JS function that doesn't exist. - // Fixing crbug.com/53610 should fix this as well. - if ((!RenderThread::current()->IsExtensionProcess() || - !ExtensionRendererInfo::ExtensionBindingsAllowed(url)) && - !content_script) { + std::string extension_id; + if (url.SchemeIs(chrome::kExtensionScheme)) { + extension_id = url.host(); + } else if (!content_script) { // This context is a regular non-extension web page. Ignore it. We only // care about content scripts and extension frames. // (Unless we're in unit tests, in which case we don't care what the URL @@ -277,10 +268,6 @@ void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) { DCHECK(frame_context.IsEmpty() || frame_context == context); if (!in_unit_tests) return; - - // For tests, we want the dispatchOnLoad to actually setup our bindings, - // so we give a fake extension id; - extension_id = kTestingExtensionId; } v8::Persistent<v8::Context> persistent_context = diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h index 037a1eb..98a56cf 100644 --- a/chrome/renderer/extensions/event_bindings.h +++ b/chrome/renderer/extensions/event_bindings.h @@ -22,8 +22,6 @@ class WebFrame; class EventBindings { public: static const char* kName; // The v8::Extension name, for dependencies. - static const char* kTestingExtensionId; - static v8::Extension* Get(); // Allow RenderThread to be mocked out. diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index 38d2919..f0da91d 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -23,7 +23,6 @@ #include "chrome/common/url_constants.h" #include "chrome/renderer/extensions/bindings_utils.h" #include "chrome/renderer/extensions/event_bindings.h" -#include "chrome/renderer/extensions/extension_renderer_info.h" #include "chrome/renderer/extensions/js_only_v8_extensions.h" #include "chrome/renderer/extensions/renderer_extension_bindings.h" #include "chrome/renderer/user_script_slave.h" @@ -57,11 +56,11 @@ namespace { // A map of extension ID to vector of page action ids. typedef std::map< std::string, std::vector<std::string> > PageActionIdMap; -// A list of permissions that are enabled for this extension. -typedef std::vector<std::string> PermissionsList; +// A map of permission name to whether its enabled for this extension. +typedef std::map<std::string, bool> PermissionsMap; // A map of extension ID to permissions map. -typedef std::map<std::string, PermissionsList> ExtensionPermissionsList; +typedef std::map<std::string, PermissionsMap> ExtensionPermissionsMap; // A map of extension ID to whether this extension was enabled in incognito. typedef std::map<std::string, bool> IncognitoEnabledMap; @@ -75,10 +74,26 @@ const char* kExtensionDeps[] = { ExtensionApiTestV8Extension::kName, }; +// A list of the API packages which have no associated permission. +// TODO(erikkay) It might be nice if for consistency we could merge these with +// the permissions list, or at least have them in one place. +const char* kNonPermissionExtensionPackages[] = { + "extension", + // TODO(erikkay): We're inconsistent about the the package name in the events + // for pageAction and browserAction. + "pageAction", + "pageActions", + "browserAction", + "browserActions", + "i18n", + "devtools", + "test" +}; + struct SingletonData { std::set<std::string> function_names_; PageActionIdMap page_action_ids_; - ExtensionPermissionsList permissions_; + ExtensionPermissionsMap permissions_; IncognitoEnabledMap incognito_enabled_map_; }; @@ -90,7 +105,7 @@ static PageActionIdMap* GetPageActionMap() { return &Singleton<SingletonData>()->page_action_ids_; } -static PermissionsList* GetPermissionsList(const std::string& extension_id) { +static PermissionsMap* GetPermissionsMap(const std::string& extension_id) { return &Singleton<SingletonData>()->permissions_[extension_id]; } @@ -99,10 +114,10 @@ static IncognitoEnabledMap* GetIncognitoEnabledMap() { } static void GetActiveExtensionIDs(std::set<std::string>* extension_ids) { - ExtensionPermissionsList& permissions = + ExtensionPermissionsMap& permissions = Singleton<SingletonData>()->permissions_; - for (ExtensionPermissionsList::iterator iter = permissions.begin(); + for (ExtensionPermissionsMap::iterator iter = permissions.begin(); iter != permissions.end(); ++iter) { extension_ids->insert(iter->first); } @@ -219,10 +234,10 @@ class ExtensionImpl : public ExtensionBase { return std::string(); // this can happen as a tab is closing. GURL url = renderview->webview()->mainFrame()->url(); - if (!ExtensionRendererInfo::ExtensionBindingsAllowed(url)) + if (!url.SchemeIs(chrome::kExtensionScheme)) return std::string(); - return ExtensionRendererInfo::GetIdByURL(url); + return url.host(); } virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( @@ -626,8 +641,13 @@ void ExtensionProcessBindings::SetPageActions( void ExtensionProcessBindings::SetAPIPermissions( const std::string& extension_id, const std::vector<std::string>& permissions) { - PermissionsList& permissions_list = *GetPermissionsList(extension_id); - permissions_list.assign(permissions.begin(), permissions.end()); + PermissionsMap& permissions_map = *GetPermissionsMap(extension_id); + + // Default all the API permissions to off. We will reset them below. + for (size_t i = 0; i < Extension::kNumPermissions; ++i) + permissions_map[Extension::kPermissionNames[i]] = false; + for (size_t i = 0; i < permissions.size(); ++i) + permissions_map[permissions[i]] = true; } // static @@ -672,8 +692,17 @@ bool ExtensionProcessBindings::HasPermission(const std::string& extension_id, if (separator != std::string::npos) permission_name = permission.substr(0, separator); - PermissionsList& permissions_list = *GetPermissionsList(extension_id); - return Extension::HasApiPermission(permissions_list, permission_name); + // windows and tabs are the same permission. + if (permission_name == "windows") + permission_name = Extension::kTabPermission; + + for (size_t i = 0; i < arraysize(kNonPermissionExtensionPackages); ++i) + if (permission_name == kNonPermissionExtensionPackages[i]) + return true; + + PermissionsMap& permissions_map = *GetPermissionsMap(extension_id); + PermissionsMap::iterator it = permissions_map.find(permission_name); + return (it != permissions_map.end() && it->second); } // static diff --git a/chrome/renderer/extensions/extension_renderer_info.cc b/chrome/renderer/extensions/extension_renderer_info.cc index f4b61a1..9abd4f5 100644 --- a/chrome/renderer/extensions/extension_renderer_info.cc +++ b/chrome/renderer/extensions/extension_renderer_info.cc @@ -29,7 +29,6 @@ void ExtensionRendererInfo::Update(const ViewMsg_ExtensionRendererInfo& info) { id_ = info.id; web_extent_ = info.web_extent; name_ = info.name; - location_ = info.location; icon_url_ = info.icon_url; } @@ -47,18 +46,6 @@ void ExtensionRendererInfo::UpdateExtensions( } // static -std::string ExtensionRendererInfo::GetIdByURL(const GURL& url) { - if (url.SchemeIs(chrome::kExtensionScheme)) - return url.host(); - - ExtensionRendererInfo* info = GetByURL(url); - if (!info) - return ""; - - return info->id(); -} - -// static ExtensionRendererInfo* ExtensionRendererInfo::GetByURL(const GURL& url) { if (url.SchemeIs(chrome::kExtensionScheme)) return GetByID(url.host()); @@ -97,21 +84,3 @@ ExtensionRendererInfo* ExtensionRendererInfo::GetByID( } return NULL; } - -// static -bool ExtensionRendererInfo::ExtensionBindingsAllowed(const GURL& url) { - if (url.SchemeIs(chrome::kExtensionScheme)) - return true; - - if (!extensions_) - return false; - - std::vector<ExtensionRendererInfo>::iterator i = extensions_->begin(); - for (; i != extensions_->end(); ++i) { - if (i->location_ == Extension::COMPONENT && - i->web_extent_.ContainsURL(url)) - return true; - } - - return false; -} diff --git a/chrome/renderer/extensions/extension_renderer_info.h b/chrome/renderer/extensions/extension_renderer_info.h index 926f275..ec0d9a3 100644 --- a/chrome/renderer/extensions/extension_renderer_info.h +++ b/chrome/renderer/extensions/extension_renderer_info.h @@ -10,7 +10,6 @@ #include <vector> #include "base/gtest_prod_util.h" -#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_extent.h" #include "googleurl/src/gurl.h" @@ -35,13 +34,6 @@ class ExtensionRendererInfo { // Returns the extension ID that the given URL is a part of, or empty if // none. This includes web URLs that are part of an extension's web extent. - static std::string GetIdByURL(const GURL& url); - - // Returns the ExtensionRendererInfo that the given URL is a part of, or NULL - // if none. This includes web URLs that are part of an extension's web extent. - // NOTE: This can return NULL if called before UpdateExtensions receives - // bulk extension data (e.g. if called from - // EventBindings::HandleContextCreated) static ExtensionRendererInfo* GetByURL(const GURL& url); // Returns true if |new_url| is in the extent of the same extension as @@ -51,11 +43,6 @@ class ExtensionRendererInfo { // Look up an ExtensionInfo object by id. static ExtensionRendererInfo* GetByID(const std::string& id); - // Returns true if |url| should get extension api bindings and be permitted - // to make api calls. Note that this is independent of what extension - // permissions the given extension has been granted. - static bool ExtensionBindingsAllowed(const GURL& url); - private: void Update(const ViewMsg_ExtensionRendererInfo& info); @@ -64,7 +51,6 @@ class ExtensionRendererInfo { std::string id_; ExtensionExtent web_extent_; std::string name_; - Extension::Location location_; GURL icon_url_; // static diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc index 484ba54..636e33f 100644 --- a/chrome/renderer/mock_render_thread.cc +++ b/chrome/renderer/mock_render_thread.cc @@ -10,7 +10,6 @@ #include "base/process_util.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" -#include "chrome/common/url_constants.h" #include "ipc/ipc_message_utils.h" #include "ipc/ipc_sync_message.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h index 54c0c44..d4ee0aa 100644 --- a/chrome/renderer/mock_render_thread.h +++ b/chrome/renderer/mock_render_thread.h @@ -56,6 +56,7 @@ class MockRenderThread : public RenderThreadBase { virtual bool IsExtensionProcess() const { return is_extension_process_; } void SetExtensionProcess(bool value) { is_extension_process_ = value; } + ////////////////////////////////////////////////////////////////////////// // The following functions are called by the test itself. diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index a3f0120..4ad6a3f 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -853,46 +853,32 @@ void RenderThread::EnsureWebKitInitialized() { WebScriptController::registerExtension( extensions_v8::ExternalExtension::Get()); - // TODO(rafaelw). Note that extension-related v8 extensions are being - // bound currently based on is_extension_process_. This means that - // non-extension renderers that slip into an extension process (for example, - // an extension page opening an iframe) will be extension bindings setup. - // This should be relatively rare, and the offending page won't be able to - // make extension API requests because it'll be denied on both sides of - // the renderer by a permission check. However, this is still fairly lame - // and we should consider implementing a V8Proxy delegate that calls out - // to the render thread and makes a decision as to whether to bind these - // extensions based on the frame's url. - // See: crbug.com/53610. + const WebKit::WebString kExtensionScheme = + WebKit::WebString::fromUTF8(chrome::kExtensionScheme); - if (is_extension_process_) - WebScriptController::registerExtension(ExtensionProcessBindings::Get()); + WebScriptController::registerExtension( + ExtensionProcessBindings::Get(), kExtensionScheme); WebScriptController::registerExtension( BaseJsV8Extension::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(BaseJsV8Extension::Get()); - + WebScriptController::registerExtension( + BaseJsV8Extension::Get(), kExtensionScheme); WebScriptController::registerExtension( JsonSchemaJsV8Extension::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(JsonSchemaJsV8Extension::Get()); - + WebScriptController::registerExtension(JsonSchemaJsV8Extension::Get(), + kExtensionScheme); WebScriptController::registerExtension( EventBindings::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(EventBindings::Get()); - + WebScriptController::registerExtension(EventBindings::Get(), + kExtensionScheme); WebScriptController::registerExtension( RendererExtensionBindings::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension(RendererExtensionBindings::Get()); - + WebScriptController::registerExtension( + RendererExtensionBindings::Get(), kExtensionScheme); + WebScriptController::registerExtension( + ExtensionApiTestV8Extension::Get(), kExtensionScheme); WebScriptController::registerExtension( ExtensionApiTestV8Extension::Get(), EXTENSION_GROUP_CONTENT_SCRIPTS); - if (is_extension_process_) - WebScriptController::registerExtension( - ExtensionApiTestV8Extension::Get()); web_database_observer_impl_.reset(new WebDatabaseObserverImpl(this)); WebKit::WebDatabase::setObserver(web_database_observer_impl_.get()); diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index f5856a7..fee9b4c 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -27,9 +27,6 @@ var chrome = chrome || {}; // ensure we don't expose the APIs in that case. if (!IsExtensionProcess()) { chromeHidden.onLoad.addListener(function (extensionId) { - if (!extensionId) { - return; - } chrome.initExtension(extensionId, false); }); return; @@ -299,9 +296,6 @@ var chrome = chrome || {}; } chromeHidden.onLoad.addListener(function (extensionId) { - if (!extensionId) { - return; - } chrome.initExtension(extensionId, false); // |apiFunctions| is a hash of name -> object that stores the |