diff options
-rw-r--r-- | chrome/browser/extensions/extension_messages_unittest.cc | 69 | ||||
-rw-r--r-- | chrome/renderer/extensions/renderer_extension_bindings.cc | 21 |
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(); |