| Index: google_apis/gcm/engine/connection_handler_impl.cc
|
| diff --git a/google_apis/gcm/engine/connection_handler_impl.cc b/google_apis/gcm/engine/connection_handler_impl.cc
|
| index 751b1cd1daa52fabcbcc583cdcc6d61b04e37861..ccb6362936bdd71ff14b72b1e475d9b3831df9dc 100644
|
| --- a/google_apis/gcm/engine/connection_handler_impl.cc
|
| +++ b/google_apis/gcm/engine/connection_handler_impl.cc
|
| @@ -22,7 +22,13 @@ namespace {
|
| const int kVersionPacketLen = 1;
|
| // # of bytes a tag packet consumes.
|
| const int kTagPacketLen = 1;
|
| -// Max # of bytes a length packet consumes.
|
| +// Max # of bytes a length packet consumes. A Varint32 can consume up to 5 bytes
|
| +// (the MSB in each byte is reserved for denoting whether more bytes follow).
|
| +// But, the protocol only allows for 4KiB payloads, and the socket stream buffer
|
| +// is only of size 8KiB. As such we should never need more than 2 bytes (max
|
| +// value of 16KiB). Anything higher than that will result in an error, either
|
| +// because the socket stream buffer overflowed or too many bytes were required
|
| +// in the size packet.
|
| const int kSizePacketLenMin = 1;
|
| const int kSizePacketLenMax = 2;
|
|
|
| @@ -321,7 +327,7 @@ void ConnectionHandlerImpl::OnGotMessageSize() {
|
| }
|
|
|
| bool need_another_byte = false;
|
| - int prev_byte_count = input_stream_->ByteCount();
|
| + int prev_byte_count = input_stream_->UnreadByteCount();
|
| {
|
| CodedInputStream coded_input_stream(input_stream_.get());
|
| if (!coded_input_stream.ReadVarint32(&message_size_))
|
| @@ -332,12 +338,12 @@ void ConnectionHandlerImpl::OnGotMessageSize() {
|
| DVLOG(1) << "Expecting another message size byte.";
|
| if (prev_byte_count >= kSizePacketLenMax) {
|
| // Already had enough bytes, something else went wrong.
|
| - LOG(ERROR) << "Failed to process message size.";
|
| - read_callback_.Run(scoped_ptr<google::protobuf::MessageLite>());
|
| + LOG(ERROR) << "Failed to process message size, too many bytes needed.";
|
| + connection_callback_.Run(net::ERR_FILE_TOO_BIG);
|
| return;
|
| }
|
| // Back up by the amount read (should always be 1 byte).
|
| - int bytes_read = prev_byte_count - input_stream_->ByteCount();
|
| + int bytes_read = prev_byte_count - input_stream_->UnreadByteCount();
|
| DCHECK_EQ(bytes_read, 1);
|
| input_stream_->BackUp(bytes_read);
|
| WaitForData(MCS_FULL_SIZE);
|
| @@ -367,8 +373,7 @@ void ConnectionHandlerImpl::OnGotMessageBytes() {
|
| return;
|
| }
|
|
|
| - if (!protobuf.get() ||
|
| - input_stream_->GetState() != SocketInputStream::READY) {
|
| + if (input_stream_->GetState() != SocketInputStream::READY) {
|
| LOG(ERROR) << "Failed to extract protobuf bytes of type "
|
| << static_cast<unsigned int>(message_tag_);
|
| // Reset the connection.
|
| @@ -376,6 +381,13 @@ void ConnectionHandlerImpl::OnGotMessageBytes() {
|
| return;
|
| }
|
|
|
| + if (!protobuf.get()) {
|
| + LOG(ERROR) << "Received message of invalid type "
|
| + << static_cast<unsigned int>(message_tag_);
|
| + connection_callback_.Run(net::ERR_INVALID_ARGUMENT);
|
| + return;
|
| + }
|
| +
|
| {
|
| CodedInputStream coded_input_stream(input_stream_.get());
|
| if (!protobuf->ParsePartialFromCodedStream(&coded_input_stream)) {
|
|
|