| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ipc/ipc_channel_reader.h" | 5 #include "ipc/ipc_channel_reader.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ipc/ipc_listener.h" | 9 #include "ipc/ipc_listener.h" |
| 10 #include "ipc/ipc_logging.h" | 10 #include "ipc/ipc_logging.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 bool ChannelReader::TranslateInputData(const char* input_data, | 71 bool ChannelReader::TranslateInputData(const char* input_data, |
| 72 int input_data_len) { | 72 int input_data_len) { |
| 73 const char* p; | 73 const char* p; |
| 74 const char* end; | 74 const char* end; |
| 75 | 75 |
| 76 // Possibly combine with the overflow buffer to make a larger buffer. | 76 // Possibly combine with the overflow buffer to make a larger buffer. |
| 77 if (input_overflow_buf_.empty()) { | 77 if (input_overflow_buf_.empty()) { |
| 78 p = input_data; | 78 p = input_data; |
| 79 end = input_data + input_data_len; | 79 end = input_data + input_data_len; |
| 80 } else { | 80 } else { |
| 81 if (input_overflow_buf_.size() + input_data_len > | 81 if (!CheckMessageSize(input_overflow_buf_.size() + input_data_len)) |
| 82 Channel::kMaximumMessageSize) { | |
| 83 input_overflow_buf_.clear(); | |
| 84 LOG(ERROR) << "IPC message is too big"; | |
| 85 return false; | 82 return false; |
| 86 } | |
| 87 input_overflow_buf_.append(input_data, input_data_len); | 83 input_overflow_buf_.append(input_data, input_data_len); |
| 88 p = input_overflow_buf_.data(); | 84 p = input_overflow_buf_.data(); |
| 89 end = p + input_overflow_buf_.size(); | 85 end = p + input_overflow_buf_.size(); |
| 90 } | 86 } |
| 91 | 87 |
| 88 size_t next_message_size = 0; |
| 89 |
| 92 // Dispatch all complete messages in the data buffer. | 90 // Dispatch all complete messages in the data buffer. |
| 93 while (p < end) { | 91 while (p < end) { |
| 94 Message::NextMessageInfo info; | 92 Message::NextMessageInfo info; |
| 95 Message::FindNext(p, end, &info); | 93 Message::FindNext(p, end, &info); |
| 96 if (info.message_found) { | 94 if (info.message_found) { |
| 97 int pickle_len = static_cast<int>(info.pickle_end - p); | 95 int pickle_len = static_cast<int>(info.pickle_end - p); |
| 98 Message translated_message(p, pickle_len); | 96 Message translated_message(p, pickle_len); |
| 99 | 97 |
| 100 for (const auto& id : info.attachment_ids) | 98 for (const auto& id : info.attachment_ids) |
| 101 translated_message.AddPlaceholderBrokerableAttachmentWithId(id); | 99 translated_message.AddPlaceholderBrokerableAttachmentWithId(id); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 120 blocked_ids_.swap(blocked_ids); | 118 blocked_ids_.swap(blocked_ids); |
| 121 StartObservingAttachmentBroker(); | 119 StartObservingAttachmentBroker(); |
| 122 } | 120 } |
| 123 | 121 |
| 124 // Make a deep copy of |translated_message| to add to the queue. | 122 // Make a deep copy of |translated_message| to add to the queue. |
| 125 scoped_ptr<Message> m(new Message(translated_message)); | 123 scoped_ptr<Message> m(new Message(translated_message)); |
| 126 queued_messages_.push_back(m.release()); | 124 queued_messages_.push_back(m.release()); |
| 127 p = info.message_end; | 125 p = info.message_end; |
| 128 } else { | 126 } else { |
| 129 // Last message is partial. | 127 // Last message is partial. |
| 128 next_message_size = info.message_size; |
| 129 if (!CheckMessageSize(next_message_size)) |
| 130 return false; |
| 130 break; | 131 break; |
| 131 } | 132 } |
| 132 } | 133 } |
| 133 | 134 |
| 134 // Save any partial data in the overflow buffer. | 135 // Save any partial data in the overflow buffer. |
| 135 input_overflow_buf_.assign(p, end - p); | 136 input_overflow_buf_.assign(p, end - p); |
| 136 | 137 |
| 138 if (!input_overflow_buf_.empty()) { |
| 139 // We have something in the overflow buffer, which means that we will |
| 140 // append the next data chunk (instead of parsing it directly). So we |
| 141 // resize the buffer to fit the next message, to avoid repeatedly |
| 142 // growing the buffer as we receive all message' data chunks. |
| 143 next_message_size += Channel::kReadBufferSize - 1; |
| 144 if (next_message_size > input_overflow_buf_.capacity()) { |
| 145 input_overflow_buf_.reserve(next_message_size); |
| 146 } |
| 147 } |
| 148 |
| 137 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) | 149 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) |
| 138 return false; | 150 return false; |
| 139 return true; | 151 return true; |
| 140 } | 152 } |
| 141 | 153 |
| 142 ChannelReader::DispatchState ChannelReader::DispatchMessages() { | 154 ChannelReader::DispatchState ChannelReader::DispatchMessages() { |
| 143 while (!queued_messages_.empty()) { | 155 while (!queued_messages_.empty()) { |
| 144 if (!blocked_ids_.empty()) | 156 if (!blocked_ids_.empty()) |
| 145 return DISPATCH_WAITING_ON_BROKER; | 157 return DISPATCH_WAITING_ON_BROKER; |
| 146 | 158 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 GetAttachmentBroker()->AddObserver(this); | 254 GetAttachmentBroker()->AddObserver(this); |
| 243 #endif // USE_ATTACHMENT_BROKER | 255 #endif // USE_ATTACHMENT_BROKER |
| 244 } | 256 } |
| 245 | 257 |
| 246 void ChannelReader::StopObservingAttachmentBroker() { | 258 void ChannelReader::StopObservingAttachmentBroker() { |
| 247 #if USE_ATTACHMENT_BROKER | 259 #if USE_ATTACHMENT_BROKER |
| 248 GetAttachmentBroker()->RemoveObserver(this); | 260 GetAttachmentBroker()->RemoveObserver(this); |
| 249 #endif // USE_ATTACHMENT_BROKER | 261 #endif // USE_ATTACHMENT_BROKER |
| 250 } | 262 } |
| 251 | 263 |
| 264 bool ChannelReader::CheckMessageSize(size_t size) { |
| 265 if (size <= Channel::kMaximumMessageSize) { |
| 266 return true; |
| 267 } |
| 268 input_overflow_buf_.clear(); |
| 269 LOG(ERROR) << "IPC message is too big: " << size; |
| 270 return false; |
| 271 } |
| 272 |
| 252 } // namespace internal | 273 } // namespace internal |
| 253 } // namespace IPC | 274 } // namespace IPC |
| OLD | NEW |