summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-13 14:43:02 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-13 14:43:02 +0000
commit173e5e807c62bb789ad46598e46367e019180568 (patch)
treef7d90e64a28b55e2e8417a2ab8ad997392c5836a /chrome
parentc0a9f12a2dbb98ff17d9fd02b250c5deeeed9a85 (diff)
downloadchromium_src-173e5e807c62bb789ad46598e46367e019180568.zip
chromium_src-173e5e807c62bb789ad46598e46367e019180568.tar.gz
chromium_src-173e5e807c62bb789ad46598e46367e019180568.tar.bz2
Reland 44348 Add support for restricting broadcasting events to extensions based on host permissions
BUG=38398 TEST=none TBR=jochen@chromium.org Review URL: http://codereview.chromium.org/1642005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44351 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider.cc2
-rw-r--r--chrome/browser/automation/extension_port_container.cc5
-rw-r--r--chrome/browser/automation/extension_port_container.h6
-rw-r--r--chrome/browser/debugger/extension_ports_remote_service.cc5
-rw-r--r--chrome/browser/debugger/extension_ports_remote_service.h6
-rw-r--r--chrome/browser/extensions/extension_accessibility_api.cc2
-rw-r--r--chrome/browser/extensions/extension_bookmark_manager_api.cc2
-rw-r--r--chrome/browser/extensions/extension_bookmarks_module.cc4
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.cc4
-rw-r--r--chrome/browser/extensions/extension_devtools_bridge.cc6
-rw-r--r--chrome/browser/extensions/extension_history_api.cc2
-rw-r--r--chrome/browser/extensions/extension_idle_api.cc3
-rw-r--r--chrome/browser/extensions/extension_menu_manager.cc2
-rw-r--r--chrome/browser/extensions/extension_menu_manager_unittest.cc8
-rw-r--r--chrome/browser/extensions/extension_message_service.cc19
-rw-r--r--chrome/browser/extensions/extension_message_service.h8
-rw-r--r--chrome/browser/extensions/extension_messages_apitest.cc51
-rw-r--r--chrome/browser/extensions/extension_messages_unittest.cc7
-rw-r--r--chrome/browser/extensions/extension_popup_api.cc5
-rw-r--r--chrome/browser/extensions/extension_toolstrip_api.cc4
-rwxr-xr-xchrome/common/extensions/api/extension_api.json19
-rw-r--r--chrome/common/extensions/extension.cc8
-rw-r--r--chrome/common/extensions/extension.h3
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/renderer/extensions/event_bindings.cc38
-rw-r--r--chrome/renderer/extensions/event_bindings.h6
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc2
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.cc6
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.h4
-rw-r--r--chrome/renderer/render_thread.cc6
-rw-r--r--chrome/renderer/render_thread.h3
-rw-r--r--chrome/renderer/render_view.cc5
-rw-r--r--chrome/renderer/render_view.h3
-rw-r--r--chrome/test/data/extensions/api_test/messaging/event_url/manifest.json7
-rw-r--r--chrome/test/data/extensions/api_test/messaging/event_url/test.html26
35 files changed, 227 insertions, 65 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 1aac1b1..e6a0360 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -2202,7 +2202,7 @@ bool AutomationProvider::InterceptBrowserEventMessageFromExternalHost(
if (profile()->GetExtensionMessageService()) {
profile()->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile()->IsOffTheRecord());
+ event_name, json_args, profile()->IsOffTheRecord(), GURL());
}
return true;
diff --git a/chrome/browser/automation/extension_port_container.cc b/chrome/browser/automation/extension_port_container.cc
index e167e7e..e93f42c 100644
--- a/chrome/browser/automation/extension_port_container.cc
+++ b/chrome/browser/automation/extension_port_container.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -114,7 +114,8 @@ bool ExtensionPortContainer::Send(IPC::Message *message) {
void ExtensionPortContainer::OnExtensionMessageInvoke(
const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access) {
+ bool requires_incognito_access,
+ const GURL& event_url) {
if (function_name == ExtensionMessageService::kDispatchOnMessage) {
DCHECK_EQ(args.GetSize(), 2u);
diff --git a/chrome/browser/automation/extension_port_container.h b/chrome/browser/automation/extension_port_container.h
index b74709d..8fd8299 100644
--- a/chrome/browser/automation/extension_port_container.h
+++ b/chrome/browser/automation/extension_port_container.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,6 +13,7 @@
class AutomationProvider;
class ExtensionMessageService;
+class GURL;
class ListValue;
class MessageLoop;
class RenderViewHost;
@@ -64,7 +65,8 @@ class ExtensionPortContainer : public IPC::Message::Sender {
void OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access);
+ bool requires_incognito_access,
+ const GURL& event_url);
void OnExtensionHandleMessage(const std::string& message, int source_port_id);
void OnExtensionPortDisconnected(int source_port_id);
diff --git a/chrome/browser/debugger/extension_ports_remote_service.cc b/chrome/browser/debugger/extension_ports_remote_service.cc
index c4380d5..d2a05ea 100644
--- a/chrome/browser/debugger/extension_ports_remote_service.cc
+++ b/chrome/browser/debugger/extension_ports_remote_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -243,7 +243,8 @@ bool ExtensionPortsRemoteService::Send(IPC::Message *message) {
void ExtensionPortsRemoteService::OnExtensionMessageInvoke(
const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access) {
+ bool requires_incognito_access,
+ const GURL& event_url) {
if (function_name == ExtensionMessageService::kDispatchOnMessage) {
DCHECK_EQ(args.GetSize(), 2u);
std::string message;
diff --git a/chrome/browser/debugger/extension_ports_remote_service.h b/chrome/browser/debugger/extension_ports_remote_service.h
index 3a9e53b..6067f44 100644
--- a/chrome/browser/debugger/extension_ports_remote_service.h
+++ b/chrome/browser/debugger/extension_ports_remote_service.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -21,6 +21,7 @@
class DevToolsProtocolHandler;
class DevToolsRemoteMessage;
class DictionaryValue;
+class GURL;
class ListValue;
class Value;
@@ -75,7 +76,8 @@ class ExtensionPortsRemoteService : public DevToolsRemoteListener,
// Handles a message from the ExtensionMessageService.
void OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access);
+ bool requires_incognito_access,
+ const GURL& event_url);
// Handles a message sent from an extension through the
// ExtensionMessageService, to be passed to the external client.
void OnExtensionMessage(const std::string& message, int port_id);
diff --git a/chrome/browser/extensions/extension_accessibility_api.cc b/chrome/browser/extensions/extension_accessibility_api.cc
index 3b6a28f..aebdda2 100644
--- a/chrome/browser/extensions/extension_accessibility_api.cc
+++ b/chrome/browser/extensions/extension_accessibility_api.cc
@@ -176,7 +176,7 @@ void ExtensionAccessibilityEventRouter::DispatchEvent(
const std::string& json_args) {
if (enabled_ && profile && profile->GetExtensionMessageService()) {
profile->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile->IsOffTheRecord());
+ event_name, json_args, profile->IsOffTheRecord(), GURL());
}
}
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc
index d057731..9b577a8 100644
--- a/chrome/browser/extensions/extension_bookmark_manager_api.cc
+++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc
@@ -156,7 +156,7 @@ void ExtensionBookmarkManagerEventRouter::DispatchEvent(const char* event_name,
std::string json_args;
base::JSONWriter::Write(args, false, &json_args);
profile_->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile_->IsOffTheRecord());
+ event_name, json_args, profile_->IsOffTheRecord(), GURL());
}
void ExtensionBookmarkManagerEventRouter::DispatchDragEvent(
diff --git a/chrome/browser/extensions/extension_bookmarks_module.cc b/chrome/browser/extensions/extension_bookmarks_module.cc
index 6a8cd08..629ae76 100644
--- a/chrome/browser/extensions/extension_bookmarks_module.cc
+++ b/chrome/browser/extensions/extension_bookmarks_module.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -95,7 +95,7 @@ void ExtensionBookmarkEventRouter::DispatchEvent(Profile *profile,
const std::string json_args) {
if (profile->GetExtensionMessageService()) {
profile->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile->IsOffTheRecord());
+ event_name, json_args, profile->IsOffTheRecord(), GURL());
}
}
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc
index 9b379bc..52d26da 100644
--- a/chrome/browser/extensions/extension_browser_event_router.cc
+++ b/chrome/browser/extensions/extension_browser_event_router.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -89,7 +89,7 @@ static void DispatchEvent(Profile* profile,
const std::string json_args) {
if (profile->GetExtensionMessageService()) {
profile->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile->IsOffTheRecord());
+ event_name, json_args, profile->IsOffTheRecord(), GURL());
}
}
diff --git a/chrome/browser/extensions/extension_devtools_bridge.cc b/chrome/browser/extensions/extension_devtools_bridge.cc
index a6399d8..d452c04 100644
--- a/chrome/browser/extensions/extension_devtools_bridge.cc
+++ b/chrome/browser/extensions/extension_devtools_bridge.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -65,7 +65,7 @@ void ExtensionDevToolsBridge::InspectedTabClosing() {
// event in extensions.
std::string json("[{}]");
profile_->GetExtensionMessageService()->DispatchEventToRenderers(
- on_tab_close_event_name_, json, profile_->IsOffTheRecord());
+ on_tab_close_event_name_, json, profile_->IsOffTheRecord(), GURL());
// This may result in this object being destroyed.
extension_devtools_manager_->BridgeClosingForTab(tab_id_);
@@ -88,7 +88,7 @@ void ExtensionDevToolsBridge::OnRpcMessage(const DevToolsMessageData& data) {
&& data.method_name == kApuPageEventMessageName) {
std::string json = StringPrintf("[%s]", data.arguments[0].c_str());
profile_->GetExtensionMessageService()->DispatchEventToRenderers(
- on_page_event_name_, json, profile_->IsOffTheRecord());
+ on_page_event_name_, json, profile_->IsOffTheRecord(), GURL());
}
}
diff --git a/chrome/browser/extensions/extension_history_api.cc b/chrome/browser/extensions/extension_history_api.cc
index 1614a80..400c163 100644
--- a/chrome/browser/extensions/extension_history_api.cc
+++ b/chrome/browser/extensions/extension_history_api.cc
@@ -143,7 +143,7 @@ void ExtensionHistoryEventRouter::DispatchEvent(Profile* profile,
const std::string& json_args) {
if (profile && profile->GetExtensionMessageService()) {
profile->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile->IsOffTheRecord());
+ event_name, json_args, profile->IsOffTheRecord(), GURL());
}
}
diff --git a/chrome/browser/extensions/extension_idle_api.cc b/chrome/browser/extensions/extension_idle_api.cc
index 688e4be..949993f 100644
--- a/chrome/browser/extensions/extension_idle_api.cc
+++ b/chrome/browser/extensions/extension_idle_api.cc
@@ -152,5 +152,6 @@ void ExtensionIdleEventRouter::OnIdleStateChange(Profile* profile,
profile->GetExtensionMessageService()->DispatchEventToRenderers(
keys::kOnStateChanged,
json_args,
- profile->IsOffTheRecord());
+ profile->IsOffTheRecord(),
+ GURL());
}
diff --git a/chrome/browser/extensions/extension_menu_manager.cc b/chrome/browser/extensions/extension_menu_manager.cc
index 809085e..bbf9909 100644
--- a/chrome/browser/extensions/extension_menu_manager.cc
+++ b/chrome/browser/extensions/extension_menu_manager.cc
@@ -316,7 +316,7 @@ void ExtensionMenuManager::ExecuteCommand(Profile* profile,
base::JSONWriter::Write(&args, false, &json_args);
std::string event_name = "contextMenu/" + item->extension_id();
service->DispatchEventToRenderers(event_name, json_args,
- profile->IsOffTheRecord());
+ profile->IsOffTheRecord(), GURL());
}
void ExtensionMenuManager::Observe(NotificationType type,
diff --git a/chrome/browser/extensions/extension_menu_manager_unittest.cc b/chrome/browser/extensions/extension_menu_manager_unittest.cc
index e81fc04..bdc282e 100644
--- a/chrome/browser/extensions/extension_menu_manager_unittest.cc
+++ b/chrome/browser/extensions/extension_menu_manager_unittest.cc
@@ -201,9 +201,10 @@ class MockExtensionMessageService : public ExtensionMessageService {
explicit MockExtensionMessageService(Profile* profile) :
ExtensionMessageService(profile) {}
- MOCK_METHOD3(DispatchEventToRenderers, void(const std::string& event_name,
+ MOCK_METHOD4(DispatchEventToRenderers, void(const std::string& event_name,
const std::string& event_args,
- bool has_incognito_data));
+ bool has_incognito_data,
+ const GURL& event_url));
private:
DISALLOW_COPY_AND_ASSIGN(MockExtensionMessageService);
@@ -254,7 +255,8 @@ TEST_F(ExtensionMenuManagerTest, ExecuteCommand) {
std::string expected_event_name = "contextMenu/" + item->extension_id();
EXPECT_CALL(*mock_message_service.get(),
DispatchEventToRenderers(expected_event_name, _,
- profile.IsOffTheRecord()))
+ profile.IsOffTheRecord(),
+ GURL()))
.Times(1)
.WillOnce(SaveArg<1>(&event_args));
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 2586151..731e7b8 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -70,7 +70,7 @@ static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port,
args.Set(4, Value::CreateStringValue(target_extension_id));
CHECK(port.sender);
port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
- ExtensionMessageService::kDispatchOnConnect, args, false));
+ ExtensionMessageService::kDispatchOnConnect, args, false, GURL()));
}
static void DispatchOnDisconnect(
@@ -78,7 +78,7 @@ static void DispatchOnDisconnect(
ListValue args;
args.Set(0, Value::CreateIntegerValue(source_port_id));
port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
- ExtensionMessageService::kDispatchOnDisconnect, args, false));
+ ExtensionMessageService::kDispatchOnDisconnect, args, false, GURL()));
}
static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
@@ -87,18 +87,20 @@ static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
args.Set(0, Value::CreateStringValue(message));
args.Set(1, Value::CreateIntegerValue(source_port_id));
port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
- ExtensionMessageService::kDispatchOnMessage, args, false));
+ ExtensionMessageService::kDispatchOnMessage, args, false, GURL()));
}
static void DispatchEvent(const ExtensionMessageService::MessagePort& port,
const std::string& event_name,
const std::string& event_args,
- bool has_incognito_data) {
+ bool has_incognito_data,
+ const GURL& event_url) {
ListValue args;
args.Set(0, Value::CreateStringValue(event_name));
args.Set(1, Value::CreateStringValue(event_args));
port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
- ExtensionMessageService::kDispatchEvent, args, has_incognito_data));
+ ExtensionMessageService::kDispatchEvent, args, has_incognito_data,
+ event_url));
}
} // namespace
@@ -456,7 +458,7 @@ void ExtensionMessageService::PostMessageFromRenderer(
void ExtensionMessageService::DispatchEventToRenderers(
const std::string& event_name, const std::string& event_args,
- bool has_incognito_data) {
+ bool has_incognito_data, const GURL& event_url) {
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
std::set<int>& pids = listeners_[event_name];
@@ -472,7 +474,8 @@ void ExtensionMessageService::DispatchEventToRenderers(
continue;
}
- DispatchEvent(renderer, event_name, event_args, has_incognito_data);
+ DispatchEvent(
+ renderer, event_name, event_args, has_incognito_data, event_url);
}
}
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index 7d7540e..c205bb9 100644
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -16,6 +16,7 @@
#include "chrome/browser/extensions/extension_devtools_manager.h"
#include "ipc/ipc_message.h"
+class GURL;
class MessageLoop;
class Profile;
class RenderProcessHost;
@@ -80,10 +81,13 @@ class ExtensionMessageService
// Sends a message from a renderer to the given port.
void PostMessageFromRenderer(int port_id, const std::string& message);
- // Send an event to every registered extension renderer.
+ // Send an event to every registered extension renderer. If
+ // |has_incognito_data| is true, the event is only sent to extension with the
+ // permission to access incognito data. If |event_url| is not empty, the
+ // event is only sent to extension with host permissions for this url.
virtual void DispatchEventToRenderers(
const std::string& event_name, const std::string& event_args,
- bool has_incognito_data);
+ bool has_incognito_data, const GURL& event_url);
// Given an extension ID, opens a channel between the given
// automation "port" or DevTools service and that extension. the
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc
index e2e969f..cc412d9 100644
--- a/chrome/browser/extensions/extension_messages_apitest.cc
+++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -3,6 +3,50 @@
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/extensions/extension_message_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/notification_registrar.h"
+
+namespace {
+
+class MessageSender : public NotificationObserver {
+ public:
+ MessageSender() {
+ registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
+ NotificationService::AllSources());
+ }
+
+ private:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ ExtensionMessageService* message_service =
+ Source<Profile>(source).ptr()->GetExtensionMessageService();
+
+ // Sends four messages to the extension. All but the third message sent
+ // from the origin http://b.com/ are supposed to arrive.
+ message_service->DispatchEventToRenderers("test.onMessage",
+ "[{\"lastMessage\":false,\"data\":\"no restriction\"}]",
+ Source<Profile>(source).ptr()->IsOffTheRecord(),
+ GURL());
+ message_service->DispatchEventToRenderers("test.onMessage",
+ "[{\"lastMessage\":false,\"data\":\"http://a.com/\"}]",
+ Source<Profile>(source).ptr()->IsOffTheRecord(),
+ GURL("http://a.com/"));
+ message_service->DispatchEventToRenderers("test.onMessage",
+ "[{\"lastMessage\":false,\"data\":\"http://b.com/\"}]",
+ Source<Profile>(source).ptr()->IsOffTheRecord(),
+ GURL("http://b.com/"));
+ message_service->DispatchEventToRenderers("test.onMessage",
+ "[{\"lastMessage\":true,\"data\":\"last message\"}]",
+ Source<Profile>(source).ptr()->IsOffTheRecord(),
+ GURL());
+ }
+
+ NotificationRegistrar registrar_;
+};
+
+} // namespace
// Tests that message passing between extensions and content scripts works.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Messaging) {
@@ -20,3 +64,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingExternal) {
ASSERT_TRUE(RunExtensionTest("messaging/connect_external")) << message_;
}
+
+// Tests that messages with event_urls are only passed to extensions with
+// appropriate permissions.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingEventURL) {
+ MessageSender sender;
+ ASSERT_TRUE(RunExtensionTest("messaging/event_url")) << message_;
+}
diff --git a/chrome/browser/extensions/extension_messages_unittest.cc b/chrome/browser/extensions/extension_messages_unittest.cc
index 5d06654..b90e92f 100644
--- a/chrome/browser/extensions/extension_messages_unittest.cc
+++ b/chrome/browser/extensions/extension_messages_unittest.cc
@@ -18,14 +18,15 @@ static void DispatchOnConnect(int source_port_id, const std::string& name,
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);
+ ExtensionMessageService::kDispatchOnConnect, args, NULL, false, GURL());
}
static void DispatchOnDisconnect(int source_port_id) {
ListValue args;
args.Set(0, Value::CreateIntegerValue(source_port_id));
RendererExtensionBindings::Invoke(
- ExtensionMessageService::kDispatchOnDisconnect, args, NULL, false);
+ ExtensionMessageService::kDispatchOnDisconnect, args, NULL, false,
+ GURL());
}
static void DispatchOnMessage(const std::string& message, int source_port_id) {
@@ -33,7 +34,7 @@ static void DispatchOnMessage(const std::string& message, int source_port_id) {
args.Set(0, Value::CreateStringValue(message));
args.Set(1, Value::CreateIntegerValue(source_port_id));
RendererExtensionBindings::Invoke(
- ExtensionMessageService::kDispatchOnMessage, args, NULL, false);
+ ExtensionMessageService::kDispatchOnMessage, args, NULL, false, GURL());
}
// Tests that the bindings for opening a channel to an extension and sending
diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc
index f73dc7f..a6f85f2 100644
--- a/chrome/browser/extensions/extension_popup_api.cc
+++ b/chrome/browser/extensions/extension_popup_api.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -353,5 +353,6 @@ void PopupEventRouter::OnPopupClosed(Profile* profile,
profile->GetExtensionMessageService()->DispatchEventToRenderers(
full_event_name,
base::JSONWriter::kEmptyArray,
- profile->IsOffTheRecord());
+ profile->IsOffTheRecord(),
+ GURL());
}
diff --git a/chrome/browser/extensions/extension_toolstrip_api.cc b/chrome/browser/extensions/extension_toolstrip_api.cc
index a858150..3732c68 100644
--- a/chrome/browser/extensions/extension_toolstrip_api.cc
+++ b/chrome/browser/extensions/extension_toolstrip_api.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -145,7 +145,7 @@ void ToolstripEventRouter::DispatchEvent(Profile *profile,
base::JSONWriter::Write(&json, false, &json_args);
std::string full_event_name = StringPrintf(event_name, routing_id);
profile->GetExtensionMessageService()->DispatchEventToRenderers(
- full_event_name, json_args, profile->IsOffTheRecord());
+ full_event_name, json_args, profile->IsOffTheRecord(), GURL());
}
}
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 30b3f12..51434bc 100755
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -2710,7 +2710,24 @@
]
}
],
- "events": []
+ "events": [
+ {
+ "name": "onMessage",
+ "type": "function",
+ "unprivileged": true,
+ "description": "Used to test sending messages to extensions.",
+ "parameters": [
+ {
+ "type": "object",
+ "name": "info",
+ "properties": {
+ "data": { "type": "string", "description": "Additional information." },
+ "lastMessage": { "type": "boolean", "description": "True if this was the last message for this test" }
+ }
+ }
+ ]
+ }
+ ]
},
{
"namespace": "experimental.clipboard",
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 2e8b5bf..0ec3183 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -885,6 +885,11 @@ void Extension::DecodeIconFromPath(const FilePath& icon_path,
result->swap(decoded);
}
+GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) {
+ return GURL(std::string(chrome::kExtensionScheme) +
+ chrome::kStandardSchemeSeparator + extension_id + "/");
+}
+
bool Extension::InitFromValue(const DictionaryValue& source, bool require_key,
std::string* error) {
if (source.HasKey(keys::kPublicKey)) {
@@ -912,8 +917,7 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key,
manifest_value_.reset(static_cast<DictionaryValue*>(source.DeepCopy()));
// Initialize the URL.
- extension_url_ = GURL(std::string(chrome::kExtensionScheme) +
- chrome::kStandardSchemeSeparator + id_ + "/");
+ extension_url_ = Extension::GetBaseURLFromExtensionId(id_);
// Initialize version.
std::string version_str;
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 7d6ac39..6cc385c 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -203,6 +203,9 @@ class Extension {
Icons icon_size,
scoped_ptr<SkBitmap>* result);
+ // Returns the base extension url for a given |extension_id|.
+ static GURL GetBaseURLFromExtensionId(const std::string& extension_id);
+
// Initialize the extension from a parsed manifest.
// Usually, the id of an extension is generated by the "key" property of
// its manifest, but if |require_key| is |false|, a temporary ID will be
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index a1028b2..bbfd9d1 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -716,10 +716,11 @@ IPC_BEGIN_MESSAGES(View)
// target process. If routed, it will be restricted to the contexts that
// are part of the target RenderView.
// |args| is a list of primitive Value types that are passed to the function.
- IPC_MESSAGE_ROUTED3(ViewMsg_ExtensionMessageInvoke,
+ IPC_MESSAGE_ROUTED4(ViewMsg_ExtensionMessageInvoke,
std::string /* function_name */,
ListValue /* args */,
- bool /* requires incognito access */)
+ bool /* requires incognito access */,
+ GURL /* event URL */)
// Tell the renderer process all known extension function names.
IPC_MESSAGE_CONTROL1(ViewMsg_Extension_SetFunctionNames,
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc
index f1dfa19..3e5c72b 100644
--- a/chrome/renderer/extensions/event_bindings.cc
+++ b/chrome/renderer/extensions/event_bindings.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,9 +13,12 @@
#include "chrome/renderer/extensions/js_only_v8_extensions.h"
#include "chrome/renderer/render_thread.h"
#include "chrome/renderer/render_view.h"
+#include "googleurl/src/gurl.h"
#include "grit/renderer_resources.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDataSource.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
using bindings_utils::CallFunctionInContext;
@@ -27,7 +30,10 @@ using bindings_utils::GetStringResource;
using bindings_utils::ExtensionBase;
using bindings_utils::GetPendingRequestMap;
using bindings_utils::PendingRequestMap;
+using WebKit::WebDataSource;
using WebKit::WebFrame;
+using WebKit::WebSecurityOrigin;
+using WebKit::WebURL;
static void ContextWeakReferenceCallback(v8::Persistent<v8::Value> context,
void*);
@@ -131,9 +137,23 @@ class ExtensionImpl : public ExtensionBase {
// Returns true if the extension running in the given |context| has sufficient
// permissions to access the data.
static bool HasSufficientPermissions(ContextInfo* context,
- bool requires_incognito_access) {
- return (!requires_incognito_access ||
- ExtensionProcessBindings::HasIncognitoEnabled(context->extension_id));
+ bool requires_incognito_access,
+ const GURL& event_url) {
+ v8::Context::Scope context_scope(context->context);
+
+ bool incognito_permissions_ok = (!requires_incognito_access ||
+ ExtensionProcessBindings::HasIncognitoEnabled(context->extension_id));
+ if (!incognito_permissions_ok)
+ return false;
+
+ RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
+ bool url_permissions_ok = (!event_url.is_valid() ||
+ (renderview &&
+ GURL(renderview->webview()->mainFrame()->url()).SchemeIs(
+ chrome::kExtensionScheme) &&
+ renderview->webview()->mainFrame()->securityOrigin().canRequest(
+ event_url)));
+ return url_permissions_ok;
}
} // namespace
@@ -225,7 +245,7 @@ void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) {
// Figure out the frame's URL. If the frame is loading, use its provisional
// URL, since we get this notification before commit.
- WebKit::WebDataSource* ds = frame->provisionalDataSource();
+ WebDataSource* ds = frame->provisionalDataSource();
if (!ds)
ds = frame->dataSource();
GURL url = ds->request().url();
@@ -299,7 +319,8 @@ void EventBindings::HandleContextDestroyed(WebFrame* frame) {
void EventBindings::CallFunction(const std::string& function_name,
int argc, v8::Handle<v8::Value>* argv,
RenderView* render_view,
- bool requires_incognito_access) {
+ bool requires_incognito_access,
+ const GURL& event_url) {
// We copy the context list, because calling into javascript may modify it
// out from under us. We also guard against deleted contexts by checking if
// they have been cleared first.
@@ -313,8 +334,11 @@ void EventBindings::CallFunction(const std::string& function_name,
if ((*it)->context.IsEmpty())
continue;
- if (!HasSufficientPermissions(it->get(), requires_incognito_access))
+ if (!HasSufficientPermissions(it->get(),
+ requires_incognito_access,
+ event_url)) {
continue;
+ }
v8::Handle<v8::Value> retval = CallFunctionInContext((*it)->context,
function_name, argc, argv);
diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h
index 74edb68..dd396ee 100644
--- a/chrome/renderer/extensions/event_bindings.h
+++ b/chrome/renderer/extensions/event_bindings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,6 +9,7 @@
#include "v8/include/v8.h"
+class GURL;
class RenderThreadBase;
class RenderView;
@@ -40,7 +41,8 @@ class EventBindings {
static void CallFunction(const std::string& function_name, int argc,
v8::Handle<v8::Value>* argv,
RenderView* render_view,
- bool requires_incognito_access);
+ bool requires_incognito_access,
+ const GURL& event_url);
};
#endif // CHROME_RENDERER_EXTENSIONS_EVENT_BINDINGS_H_
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index 3232237..fe8abcd 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -87,7 +87,7 @@ static PermissionsMap* GetPermissionsMap(const std::string& extension_id) {
return &Singleton<SingletonData>()->permissions_[extension_id];
}
-static std::map<std::string, bool>* GetIncognitoEnabledMap() {
+static IncognitoEnabledMap* GetIncognitoEnabledMap() {
return &Singleton<SingletonData>()->incognito_enabled_map_;
}
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc
index d393089..6c43944 100644
--- a/chrome/renderer/extensions/renderer_extension_bindings.cc
+++ b/chrome/renderer/extensions/renderer_extension_bindings.cc
@@ -299,12 +299,14 @@ v8::Extension* RendererExtensionBindings::Get() {
void RendererExtensionBindings::Invoke(const std::string& function_name,
const ListValue& args,
RenderView* renderview,
- bool requires_incognito_access) {
+ bool requires_incognito_access,
+ const GURL& event_url) {
v8::HandleScope handle_scope;
std::vector< v8::Handle<v8::Value> > argv = ListValueToV8(args);
EventBindings::CallFunction(function_name,
argv.size(),
&argv[0],
renderview,
- requires_incognito_access);
+ requires_incognito_access,
+ event_url);
}
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.h b/chrome/renderer/extensions/renderer_extension_bindings.h
index 04233f6..3e70e8f 100644
--- a/chrome/renderer/extensions/renderer_extension_bindings.h
+++ b/chrome/renderer/extensions/renderer_extension_bindings.h
@@ -9,6 +9,7 @@
#include <string>
+class GURL;
class ListValue;
class RenderView;
@@ -24,7 +25,8 @@ class RendererExtensionBindings {
// Call the given javascript function with the specified arguments.
static void Invoke(const std::string& function_name, const ListValue& args,
- RenderView* renderview, bool requires_incognito_access);
+ RenderView* renderview, bool requires_incognito_access,
+ const GURL& event_url);
};
#endif // CHROME_RENDERER_EXTENSIONS_RENDERER_EXTENSION_BINDINGS_H_
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 3a0385a..fc243d8 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -917,8 +917,10 @@ void RenderThread::ScheduleIdleHandler(double initial_delay_s) {
void RenderThread::OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access) {
- RendererExtensionBindings::Invoke(function_name, args, NULL, requires_incognito_access);
+ bool requires_incognito_access,
+ const GURL& event_url) {
+ RendererExtensionBindings::Invoke(
+ function_name, args, NULL, requires_incognito_access, event_url);
// Reset the idle handler each time there's any activity like event or message
// dispatch, for which Invoke is the chokepoint.
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 2294e05..3c45dd5 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -226,7 +226,8 @@ class RenderThread : public RenderThreadBase,
void OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access);
+ bool requires_incognito_access,
+ const GURL& event_url);
void OnPurgeMemory();
void OnPurgePluginListCache(bool reload_pages);
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 39e6ec6..a16a735 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -4298,9 +4298,10 @@ void RenderView::InjectToolstripCSS() {
void RenderView::OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access) {
+ bool requires_incognito_access,
+ const GURL& event_url) {
RendererExtensionBindings::Invoke(
- function_name, args, this, requires_incognito_access);
+ function_name, args, this, requires_incognito_access, event_url);
}
// Dump all load time histograms.
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index c3a0190..9545245 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -727,7 +727,8 @@ class RenderView : public RenderWidget,
void OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args,
- bool requires_incognito_access);
+ bool requires_incognito_access,
+ const GURL& event_url);
void OnMoveOrResizeStarted();
diff --git a/chrome/test/data/extensions/api_test/messaging/event_url/manifest.json b/chrome/test/data/extensions/api_test/messaging/event_url/manifest.json
new file mode 100644
index 0000000..1fd201f
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/messaging/event_url/manifest.json
@@ -0,0 +1,7 @@
+{
+ "name": "event_url",
+ "version": "1.0",
+ "description": "Tests messages which require permissions.",
+ "permissions": ["http://a.com/"],
+ "background_page": "test.html"
+}
diff --git a/chrome/test/data/extensions/api_test/messaging/event_url/test.html b/chrome/test/data/extensions/api_test/messaging/event_url/test.html
new file mode 100644
index 0000000..fc0bc51
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/messaging/event_url/test.html
@@ -0,0 +1,26 @@
+<script>
+var messages = [];
+
+function messageReceived(data) {
+ messages.push(data);
+}
+
+function evaluateMessages() {
+ if (messages.length != 3)
+ chrome.test.notifyFail("Got " + messages.length + " messages instead of 3");
+ else if (messages[0] != "no restriction" ||
+ messages[1] != "http://a.com/" ||
+ messages[2] != "last message")
+ chrome.test.notifyFail("Got wrong messages: " + messages[0] + ", " +
+ messages[1] + ", " + messages[2]);
+ else
+ chrome.test.notifyPass();
+}
+
+
+chrome.test.onMessage.addListener(function (info) {
+ messageReceived(info.data);
+ if (info.lastMessage)
+ evaluateMessages();
+});
+</script>