| Index: ipc/ipc_channel_reader.cc
|
| diff --git a/ipc/ipc_channel_reader.cc b/ipc/ipc_channel_reader.cc
|
| index a82093e870c299726baa90f0a88d8aafb4dc6aad..335852ffc3ff4e658ece61d0b8fae3f284660ab7 100644
|
| --- a/ipc/ipc_channel_reader.cc
|
| +++ b/ipc/ipc_channel_reader.cc
|
| @@ -15,7 +15,9 @@
|
| namespace IPC {
|
| namespace internal {
|
|
|
| -ChannelReader::ChannelReader(Listener* listener) : listener_(listener) {
|
| +ChannelReader::ChannelReader(Listener* listener)
|
| + : listener_(listener),
|
| + max_input_buffer_size_(Channel::kMaximumReadBufferSize) {
|
| memset(input_buf_, 0, sizeof(input_buf_));
|
| }
|
|
|
| @@ -114,6 +116,11 @@ bool ChannelReader::TranslateInputData(const char* input_data,
|
| }
|
| }
|
|
|
| + // Account for the case where last message's byte is in the next data chunk.
|
| + size_t next_message_buffer_size = next_message_size ?
|
| + next_message_size + Channel::kReadBufferSize - 1:
|
| + 0;
|
| +
|
| // Save any partial data in the overflow buffer.
|
| input_overflow_buf_.assign(p, end - p);
|
|
|
| @@ -122,10 +129,28 @@ bool ChannelReader::TranslateInputData(const char* input_data,
|
| // append the next data chunk (instead of parsing it directly). So we
|
| // resize the buffer to fit the next message, to avoid repeatedly
|
| // growing the buffer as we receive all message' data chunks.
|
| - next_message_size += Channel::kReadBufferSize - 1;
|
| - if (next_message_size > input_overflow_buf_.capacity()) {
|
| - input_overflow_buf_.reserve(next_message_size);
|
| + if (next_message_buffer_size > input_overflow_buf_.capacity()) {
|
| + input_overflow_buf_.reserve(next_message_buffer_size);
|
| + }
|
| + }
|
| +
|
| + // Trim the buffer if we can
|
| + if (next_message_buffer_size < max_input_buffer_size_ &&
|
| + input_overflow_buf_.size() < max_input_buffer_size_ &&
|
| + input_overflow_buf_.capacity() > max_input_buffer_size_) {
|
| + // std::string doesn't really have a method to shrink capacity to
|
| + // a specific value, so we have to swap with another string.
|
| + std::string trimmed_buf;
|
| + trimmed_buf.reserve(max_input_buffer_size_);
|
| + if (trimmed_buf.capacity() > max_input_buffer_size_) {
|
| + // Since we don't control how much space reserve() actually reserves,
|
| + // we have to go other way around and change the max size to avoid
|
| + // getting into the outer if() again.
|
| + max_input_buffer_size_ = trimmed_buf.capacity();
|
| }
|
| + trimmed_buf.assign(input_overflow_buf_.data(),
|
| + input_overflow_buf_.size());
|
| + input_overflow_buf_.swap(trimmed_buf);
|
| }
|
|
|
| if (input_overflow_buf_.empty() && !DidEmptyInputBuffers())
|
|
|