Chromium Code Reviews| Index: chrome/browser/extensions/api/cast_channel/cast_socket.cc |
| diff --git a/chrome/browser/extensions/api/cast_channel/cast_socket.cc b/chrome/browser/extensions/api/cast_channel/cast_socket.cc |
| index 6130d92e18755dc825880177b785f7536baf5afc..e4712dc9cf6d8d709bf3b7a2c0786660ff86dce0 100644 |
| --- a/chrome/browser/extensions/api/cast_channel/cast_socket.cc |
| +++ b/chrome/browser/extensions/api/cast_channel/cast_socket.cc |
| @@ -158,7 +158,7 @@ bool CastSocket::ExtractPeerCert(std::string* cert) { |
| } |
| bool CastSocket::VerifyChallengeReply() { |
| - return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_); |
| + return AuthenticateChallengeReply(*challenge_reply_, peer_cert_); |
| } |
| void CastSocket::Connect(const net::CompletionCallback& callback) { |
| @@ -532,6 +532,7 @@ void CastSocket::DoReadLoop(int result) { |
| break; |
| case READ_STATE_ERROR: |
| rv = DoReadError(rv); |
| + DCHECK_EQ(read_state_, READ_STATE_NONE); |
| break; |
| default: |
| NOTREACHED() << "BUG in read flow. Unknown state: " << state; |
| @@ -539,9 +540,18 @@ void CastSocket::DoReadLoop(int result) { |
| } |
| } while (rv != net::ERR_IO_PENDING && read_state_ != READ_STATE_NONE); |
| - // Read loop is done - If the result is ERR_FAILED then close with error. |
| - if (rv == net::ERR_FAILED) |
| - CloseWithError(error_state_); |
| + if (rv == net::ERR_FAILED) { |
| + if (ready_state_ == READY_STATE_CONNECTING) { |
| + // Connection not yet established. |
|
Wez
2014/07/23 21:27:42
nit: No need for this; should be implicit from rea
Kevin M
2014/07/23 23:40:46
Done.
|
| + // Read errors during the handshake should notify the caller via |
| + // the connect callback, rather than the message event delegate. |
| + PostTaskToStartConnectLoop(net::ERR_FAILED); |
| + } else { |
| + // Connection is already established. |
| + // Close and send error status via the message event delegate. |
| + CloseWithError(error_state_); |
| + } |
| + } |
| } |
| int CastSocket::DoRead() { |
| @@ -551,14 +561,23 @@ int CastSocket::DoRead() { |
| if (header_read_buffer_->RemainingCapacity() > 0) { |
| current_read_buffer_ = header_read_buffer_; |
| num_bytes_to_read = header_read_buffer_->RemainingCapacity(); |
| - DCHECK_LE(num_bytes_to_read, MessageHeader::header_size()); |
| + if (num_bytes_to_read > MessageHeader::header_size()) { |
| + error_state_ = CHANNEL_ERROR_INVALID_MESSAGE; |
| + return net::ERR_FAILED; |
| + } |
| } else { |
| DCHECK_GT(current_message_size_, 0U); |
| num_bytes_to_read = current_message_size_ - body_read_buffer_->offset(); |
| current_read_buffer_ = body_read_buffer_; |
| - DCHECK_LE(num_bytes_to_read, MessageHeader::max_message_size()); |
| + if (num_bytes_to_read > MessageHeader::max_message_size()) { |
| + error_state_ = CHANNEL_ERROR_INVALID_MESSAGE; |
| + return net::ERR_FAILED; |
| + } |
| + } |
| + if (num_bytes_to_read == 0) { |
| + error_state_ = CHANNEL_ERROR_INVALID_MESSAGE; |
| + return net::ERR_FAILED; |
| } |
| - DCHECK_GT(num_bytes_to_read, 0U); |
| // Read up to num_bytes_to_read into |current_read_buffer_|. |
| return socket_->Read( |
| @@ -580,8 +599,8 @@ int CastSocket::DoReadComplete(int result) { |
| } |
| // Some data was read. Move the offset in the current buffer forward. |
| - DCHECK_LE(current_read_buffer_->offset() + result, |
| - current_read_buffer_->capacity()); |
| + CHECK_LE(current_read_buffer_->offset() + result, |
| + current_read_buffer_->capacity()); |
| current_read_buffer_->set_offset(current_read_buffer_->offset() + result); |
| read_state_ = READ_STATE_READ; |
| @@ -609,40 +628,38 @@ int CastSocket::DoReadComplete(int result) { |
| int CastSocket::DoReadCallback() { |
| read_state_ = READ_STATE_READ; |
| - const CastMessage& message = *(current_message_.get()); |
| - if (IsAuthMessage(message)) { |
| - // An auth message is received, check that connect flow is running. |
| - if (ready_state_ == READY_STATE_CONNECTING) { |
| + const CastMessage& message = *current_message_; |
| + if (ready_state_ == READY_STATE_CONNECTING) { |
| + if (IsAuthMessage(message)) { |
| challenge_reply_.reset(new CastMessage(message)); |
| PostTaskToStartConnectLoop(net::OK); |
| + return net::OK; |
| } else { |
| + // Expected an auth message, got something else instead. Handle as error. |
| read_state_ = READ_STATE_ERROR; |
| + return net::ERR_INVALID_RESPONSE; |
| } |
| - } else if (delegate_) { |
| - MessageInfo message_info; |
| - if (CastMessageToMessageInfo(message, &message_info)) |
| - delegate_->OnMessage(this, message_info); |
| - else |
| - read_state_ = READ_STATE_ERROR; |
| } |
| + |
| + MessageInfo message_info; |
| + if (!CastMessageToMessageInfo(message, &message_info)) { |
| + current_message_->Clear(); |
| + read_state_ = READ_STATE_ERROR; |
| + return net::ERR_INVALID_RESPONSE; |
| + } |
| + delegate_->OnMessage(this, message_info); |
| current_message_->Clear(); |
| return net::OK; |
| } |
| int CastSocket::DoReadError(int result) { |
| DCHECK_LE(result, 0); |
| - // If inside connection flow, then get back to connect loop. |
| - if (ready_state_ == READY_STATE_CONNECTING) { |
| - PostTaskToStartConnectLoop(result); |
| - // does not try to report error also. |
| - return net::OK; |
| - } |
| return net::ERR_FAILED; |
| } |
| bool CastSocket::ProcessHeader() { |
| - DCHECK_EQ(static_cast<uint32>(header_read_buffer_->offset()), |
| - MessageHeader::header_size()); |
| + CHECK_EQ(static_cast<uint32>(header_read_buffer_->offset()), |
| + MessageHeader::header_size()); |
| MessageHeader header; |
| MessageHeader::ReadFromIOBuffer(header_read_buffer_.get(), &header); |
| if (header.message_size > MessageHeader::max_message_size()) |
| @@ -655,8 +672,10 @@ bool CastSocket::ProcessHeader() { |
| } |
| bool CastSocket::ProcessBody() { |
| - DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), |
| - current_message_size_); |
| + if (static_cast<uint32>(body_read_buffer_->offset()) != |
| + current_message_size_) { |
| + return false; |
| + } |
| if (!current_message_->ParseFromArray( |
| body_read_buffer_->StartOfBuffer(), current_message_size_)) { |
| return false; |
| @@ -679,10 +698,12 @@ bool CastSocket::Serialize(const CastMessage& message_proto, |
| return false; |
| } |
| CastSocket::MessageHeader header; |
| - header.SetMessageSize(message_size); |
| + if (!header.SetMessageSize(message_size)) { |
| + return false; |
| + } |
| header.PrependToString(message_data); |
| return true; |
| -}; |
| +} |
| void CastSocket::CloseWithError(ChannelError error) { |
| DCHECK(CalledOnValidThread()); |
| @@ -704,10 +725,13 @@ bool CastSocket::CalledOnValidThread() const { |
| CastSocket::MessageHeader::MessageHeader() : message_size(0) { } |
| -void CastSocket::MessageHeader::SetMessageSize(size_t size) { |
| - DCHECK(size < static_cast<size_t>(kuint32max)); |
| - DCHECK(size > 0); |
| +bool CastSocket::MessageHeader::SetMessageSize(size_t size) { |
| + if (size >= static_cast<size_t>(kuint32max) || |
|
Wez
2014/07/23 21:27:42
Don't we already have a check against max_message_
Ryan Sleevi
2014/07/23 22:31:13
It would matter for 64-bit
Wez
2014/07/23 22:33:31
Except that we already check against max_message_s
Kevin M
2014/07/23 23:40:46
True. Removed the check. Thanks.
|
| + size == 0) { |
| + return false; |
| + } |
| message_size = static_cast<size_t>(size); |
|
Ryan Sleevi
2014/07/23 22:31:13
Why is this static cast needed?
It feels like bot
Kevin M
2014/07/23 23:40:46
Done.
|
| + return true; |
| } |
| // TODO(mfoltz): Investigate replacing header serialization with base::Pickle, |