diff options
author | wjmaclean <wjmaclean@chromium.org> | 2015-10-16 12:57:24 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-16 19:58:27 +0000 |
commit | 6f63918adf16bbd01bba2acb42ca87755fc8f439 (patch) | |
tree | 9e1be3185f5ca51dacd9d163913cb13cf1f957bb | |
parent | ee39de0c59d369c508e3a48317964ed0ab7b61ef (diff) | |
download | chromium_src-6f63918adf16bbd01bba2acb42ca87755fc8f439.zip chromium_src-6f63918adf16bbd01bba2acb42ca87755fc8f439.tar.gz chromium_src-6f63918adf16bbd01bba2acb42ca87755fc8f439.tar.bz2 |
Update IPC browser_plugin_instance_id before sending queued messages
Currently, if BrowserPluginGuest receives messages for a BrowserPlugin
prior to attachment, the message may be created with an invalid (0)
value of |browser_plugin_instance_id|. After attachment, when queued
messages are sent, these messages disappear into the ether.
This CL modifies queued IPC messages in BrowserPluginGuest before those
messages are sent, in order to give them a valid instance id.
BUG=534839
Review URL: https://codereview.chromium.org/1410753003
Cr-Commit-Position: refs/heads/master@{#354572}
-rw-r--r-- | content/browser/browser_plugin/browser_plugin_guest.cc | 43 | ||||
-rw-r--r-- | content/browser/browser_plugin/browser_plugin_guest.h | 6 |
2 files changed, 48 insertions, 1 deletions
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index eaec2fe..2c79731 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -565,6 +565,46 @@ void BrowserPluginGuest::EmbedderSystemDragEnded() { EndSystemDragIfApplicable(); } +// TODO(wjmaclean): Replace this approach with ones based on std::function +// as in https://codereview.chromium.org/1404353004/ once all Chrome platforms +// support this. https://crbug.com/544212 +IPC::Message* BrowserPluginGuest::UpdateInstanceIdIfNecessary( + IPC::Message* msg) const { + DCHECK(msg); + + int msg_browser_plugin_instance_id = browser_plugin::kInstanceIDNone; + base::PickleIterator iter(*msg); + if (!iter.ReadInt(&msg_browser_plugin_instance_id) || + msg_browser_plugin_instance_id != browser_plugin::kInstanceIDNone) { + return msg; + } + + // This method may be called with no browser_plugin_instance_id in tests. + if (!browser_plugin_instance_id()) + return msg; + + scoped_ptr<IPC::Message> new_msg( + new IPC::Message(msg->routing_id(), msg->type(), msg->priority())); + new_msg->WriteInt(browser_plugin_instance_id()); + + // Copy remaining payload from original message. + // TODO(wjmaclean): it would be nice if IPC::PickleIterator had a method + // like 'RemainingBytes()' so that we don't have to include implementation- + // specific details like sizeof() in the next line. + DCHECK(msg->payload_size() > sizeof(int)); + size_t remaining_bytes = msg->payload_size() - sizeof(int); + const char* data = nullptr; + bool read_success = iter.ReadBytes(&data, remaining_bytes); + CHECK(read_success) + << "Unexpected failure reading remaining IPC::Message payload."; + bool write_success = new_msg->WriteBytes(data, remaining_bytes); + CHECK(write_success) + << "Unexpected failure writing remaining IPC::Message payload."; + + delete msg; + return new_msg.release(); +} + void BrowserPluginGuest::SendQueuedMessages() { if (!attached()) return; @@ -572,7 +612,8 @@ void BrowserPluginGuest::SendQueuedMessages() { while (!pending_messages_.empty()) { linked_ptr<IPC::Message> message_ptr = pending_messages_.front(); pending_messages_.pop_front(); - SendMessageToEmbedder(message_ptr.release()); + SendMessageToEmbedder( + UpdateInstanceIdIfNecessary(message_ptr.release())); } } diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index f302c6d..d739434 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h @@ -386,6 +386,12 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost, void OnWillAttachComplete(WebContentsImpl* embedder_web_contents, const BrowserPluginHostMsg_Attach_Params& params); + // Returns identical message with current browser_plugin_instance_id() if + // the input was created with browser_plugin::kInstanceIdNone, else it returns + // the input message unmodified. If no current browser_plugin_instance_id() + // is set, or anything goes wrong, the input message is returned. + IPC::Message* UpdateInstanceIdIfNecessary(IPC::Message* msg) const; + // Forwards all messages from the |pending_messages_| queue to the embedder. void SendQueuedMessages(); |