summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_messages_unittest.cc69
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.cc21
2 files changed, 18 insertions, 72 deletions
diff --git a/chrome/browser/extensions/extension_messages_unittest.cc b/chrome/browser/extensions/extension_messages_unittest.cc
index cdb78cc..98d4db0 100644
--- a/chrome/browser/extensions/extension_messages_unittest.cc
+++ b/chrome/browser/extensions/extension_messages_unittest.cc
@@ -147,72 +147,3 @@ TEST_F(RenderViewTest, ExtensionMessagesOnConnect) {
ASSERT_TRUE(IPC::ReadParam(alert_msg, &iter, &alert_param));
EXPECT_EQ(L"disconnected: 24", alert_param.a);
}
-
-// Tests that we don't send the disconnect message until all ports have
-// disconnected.
-TEST_F(RenderViewTest, ExtensionMessagesDisconnect) {
- LoadHTML("<body></body>");
- ExecuteJavaScript(
- "chrome.extension.onConnect.addListener(function (port) {"
- " port.onMessage.addListener(function(msg, p) {"
- " if (msg.disconnect) port.disconnect();"
- " });"
- "});"
- "var iframe1 = document.createElement('iframe');"
- "var iframe2 = document.createElement('iframe');"
- "var src = 'javascript:"
- " chrome.extension.onConnect.addListener(function(port) {"
- " port.postMessage(\"onconnect\");"
- " port.onMessage.addListener(function(p) { alert(\"NOTREACHED\"); });"
- " port.disconnect();"
- " });';"
- "iframe1.src = src;"
- "iframe2.src = src;"
- "document.body.appendChild(iframe1);"
- "document.body.appendChild(iframe2);");
-
- render_thread_.sink().ClearMessages();
-
- // Simulate a new connection being opened. The two child frames should
- // disconnect immediately, but we shouldn't get a disconnect message until
- // all 3 frames disconnect.
- const int kPortId = 0;
- const std::string kPortName = "testName";
- DispatchOnConnect(kPortId, kPortName, "null");
-
- // Verify that we handled the new connection by posting a message.
- const IPC::Message* post_msg =
- render_thread_.sink().GetFirstMessageMatching(
- ViewHostMsg_ExtensionPostMessage::ID);
- ASSERT_TRUE(post_msg);
- ViewHostMsg_ExtensionPostMessage::Param post_params;
- ViewHostMsg_ExtensionPostMessage::Read(post_msg, &post_params);
- EXPECT_EQ("\"onconnect\"", post_params.b);
-
- // Simulate sending a message.
- render_thread_.sink().ClearMessages();
- DispatchOnMessage("{\"val\": 42}", kPortId);
-
- // If we get an alert box, then the iframes failed to disconnect properly.
- const IPC::Message* alert_msg =
- render_thread_.sink().GetFirstMessageMatching(
- ViewHostMsg_RunJavaScriptMessage::ID);
- ASSERT_FALSE(alert_msg);
-
- // We should not get a disconnect message yet, since the toplevel frame didn't
- // disconnect.
- const IPC::Message* disconnect_msg =
- render_thread_.sink().GetFirstMessageMatching(
- ViewHostMsg_ExtensionCloseChannel::ID);
- ASSERT_FALSE(disconnect_msg);
-
- // Disconnect the port in the top frame.
- render_thread_.sink().ClearMessages();
- DispatchOnMessage("{\"disconnect\": true}", kPortId);
-
- // Now we should have a disconnect message.
- disconnect_msg =
- render_thread_.sink().GetUniqueMessageMatching(
- ViewHostMsg_ExtensionCloseChannel::ID);
- ASSERT_TRUE(disconnect_msg);
-}
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc
index de958d1..42882d07 100644
--- a/chrome/renderer/extensions/renderer_extension_bindings.cc
+++ b/chrome/renderer/extensions/renderer_extension_bindings.cc
@@ -37,10 +37,18 @@ struct ExtensionData {
};
std::map<int, PortData> ports; // port ID -> data
};
+bool HasPortData(int port_id) {
+ return Singleton<ExtensionData>::get()->ports.find(port_id) !=
+ Singleton<ExtensionData>::get()->ports.end();
+}
ExtensionData::PortData& GetPortData(int port_id) {
return Singleton<ExtensionData>::get()->ports[port_id];
}
+void ClearPortData(int port_id) {
+ Singleton<ExtensionData>::get()->ports.erase(port_id);
+}
+const char kPortClosedError[] = "Attempting to use a disconnected port object";
const char* kExtensionDeps[] = { EventBindings::kName };
class ExtensionImpl : public ExtensionBase {
@@ -99,6 +107,10 @@ class ExtensionImpl : public ExtensionBase {
if (args.Length() >= 2 && args[0]->IsInt32() && args[1]->IsString()) {
int port_id = args[0]->Int32Value();
+ if (!HasPortData(port_id)) {
+ return v8::ThrowException(v8::Exception::Error(
+ v8::String::New(kPortClosedError)));
+ }
std::string message = *v8::String::Utf8Value(args[1]->ToString());
renderview->Send(new ViewHostMsg_ExtensionPostMessage(
renderview->routing_id(), port_id, message));
@@ -110,10 +122,13 @@ class ExtensionImpl : public ExtensionBase {
static v8::Handle<v8::Value> CloseChannel(const v8::Arguments& args) {
if (args.Length() >= 1 && args[0]->IsInt32()) {
int port_id = args[0]->Int32Value();
+ if (!HasPortData(port_id)) {
+ return v8::Undefined();
+ }
// Send via the RenderThread because the RenderView might be closing.
EventBindings::GetRenderThread()->Send(
new ViewHostMsg_ExtensionCloseChannel(port_id));
- GetPortData(port_id).disconnected = true;
+ ClearPortData(port_id);
}
return v8::Undefined();
}
@@ -134,11 +149,11 @@ class ExtensionImpl : public ExtensionBase {
static v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) {
if (args.Length() >= 1 && args[0]->IsInt32()) {
int port_id = args[0]->Int32Value();
- if (!GetPortData(port_id).disconnected &&
- --GetPortData(port_id).ref_count == 0) {
+ if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
// Send via the RenderThread because the RenderView might be closing.
EventBindings::GetRenderThread()->Send(
new ViewHostMsg_ExtensionCloseChannel(port_id));
+ ClearPortData(port_id);
}
}
return v8::Undefined();