Index: ipc/ipc_message.cc |
diff --git a/ipc/ipc_message.cc b/ipc/ipc_message.cc |
index 07d5d254759a23d208829d86d924c5e207a56ce3..934fd474f04ea4e621ce2962d927502b92974b07 100644 |
--- a/ipc/ipc_message.cc |
+++ b/ipc/ipc_message.cc |
@@ -4,6 +4,8 @@ |
#include "ipc/ipc_message.h" |
+#include <limits.h> |
+ |
#include "base/atomic_sequence_num.h" |
#include "base/logging.h" |
#include "build/build_config.h" |
@@ -127,6 +129,57 @@ void Message::set_received_time(int64 time) const { |
} |
#endif |
+Message::NextMessageInfo::NextMessageInfo() |
+ : message_found(false), pickle_end(nullptr), message_end(nullptr) {} |
+Message::NextMessageInfo::~NextMessageInfo() {} |
+ |
+// static |
+void Message::FindNext(const char* range_start, |
+ const char* range_end, |
+ NextMessageInfo* info) { |
+ DCHECK(info); |
+ const char* pickle_end = |
+ base::Pickle::FindNext(sizeof(Header), range_start, range_end); |
+ if (!pickle_end) |
+ return; |
+ info->pickle_end = pickle_end; |
+ |
+#if USE_ATTACHMENT_BROKER |
+ // The data is not copied. |
+ size_t pickle_len = static_cast<size_t>(pickle_end - range_start); |
+ Message message(range_start, static_cast<int>(pickle_len)); |
+ int num_attachments = message.header()->num_brokered_attachments; |
+ |
+ // Check for possible overflows. |
+ size_t max_size_t = std::numeric_limits<size_t>::max(); |
+ if (num_attachments >= max_size_t / BrokerableAttachment::kNonceSize) |
+ return; |
+ |
+ size_t attachment_length = num_attachments * BrokerableAttachment::kNonceSize; |
+ if (pickle_len > max_size_t - attachment_length) |
+ return; |
+ |
+ // Check whether the range includes the attachments. |
+ size_t buffer_length = static_cast<size_t>(range_end - range_start); |
+ if (buffer_length < attachment_length + pickle_len) |
+ return; |
+ |
+ for (int i = 0; i < num_attachments; ++i) { |
+ const char* attachment_start = |
+ pickle_end + i * BrokerableAttachment::kNonceSize; |
+ BrokerableAttachment::AttachmentId id(attachment_start, |
+ BrokerableAttachment::kNonceSize); |
+ info->attachment_ids.push_back(id); |
+ } |
+ info->message_end = |
+ pickle_end + num_attachments * BrokerableAttachment::kNonceSize; |
+#else |
+ info->message_end = pickle_end; |
+#endif // USE_ATTACHMENT_BROKER |
+ |
+ info->message_found = true; |
+} |
+ |
bool Message::WriteAttachment(scoped_refptr<MessageAttachment> attachment) { |
// We write the index of the descriptor so that we don't have to |
// keep the current descriptor as extra decoding state when deserialising. |