From 4bff6bea4a331de69be940a4b09f024392d012c4 Mon Sep 17 00:00:00 2001 From: pkasting Date: Wed, 15 Oct 2014 10:54:34 -0700 Subject: [PATCH] Fix type truncation warnings related to WebSocketFrameHeader::payload_length being a uint64. BUG=81439 TEST=none Review URL: https://codereview.chromium.org/653713002 Cr-Commit-Position: refs/heads/master@{#299713} --- net/websockets/websocket_basic_stream.cc | 16 ++++----- net/websockets/websocket_channel.cc | 38 ++++++++++------------ net/websockets/websocket_channel.h | 24 +++++++------- net/websockets/websocket_deflate_stream.cc | 10 +++--- net/websockets/websocket_frame_parser.cc | 12 +++---- 5 files changed, 48 insertions(+), 52 deletions(-) diff --git a/net/websockets/websocket_basic_stream.cc b/net/websockets/websocket_basic_stream.cc index af2444d834a07a..2890a9e493f8a4 100644 --- a/net/websockets/websocket_basic_stream.cc +++ b/net/websockets/websocket_basic_stream.cc @@ -47,22 +47,22 @@ typedef ScopedVector::const_iterator WebSocketFrameIterator; // masked bit of the frames on. int CalculateSerializedSizeAndTurnOnMaskBit( ScopedVector* frames) { - const int kMaximumTotalSize = std::numeric_limits::max(); + const uint64 kMaximumTotalSize = std::numeric_limits::max(); - int total_size = 0; + uint64 total_size = 0; for (WebSocketFrameIterator it = frames->begin(); it != frames->end(); ++it) { WebSocketFrame* frame = *it; // Force the masked bit on. frame->header.masked = true; // We enforce flow control so the renderer should never be able to force us // to cache anywhere near 2GB of frames. - int frame_size = frame->header.payload_length + - GetWebSocketFrameHeaderSize(frame->header); - CHECK_GE(kMaximumTotalSize - total_size, frame_size) + uint64 frame_size = frame->header.payload_length + + GetWebSocketFrameHeaderSize(frame->header); + CHECK_LE(frame_size, kMaximumTotalSize - total_size) << "Aborting to prevent overflow"; total_size += frame_size; } - return total_size; + return static_cast(total_size); } } // namespace @@ -157,9 +157,9 @@ int WebSocketBasicStream::WriteFrames(ScopedVector* frames, dest += result; remaining_size -= result; - const int frame_size = frame->header.payload_length; + CHECK_LE(frame->header.payload_length, static_cast(remaining_size)); + const int frame_size = static_cast(frame->header.payload_length); if (frame_size > 0) { - CHECK_GE(remaining_size, frame_size); const char* const frame_data = frame->data->data(); std::copy(frame_data, frame_data + frame_size, dest); MaskWebSocketFramePayload(mask, 0, dest, frame_size); diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc index 02430790fb2d4f..9585dc25afb68c 100644 --- a/net/websockets/websocket_channel.cc +++ b/net/websockets/websocket_channel.cc @@ -138,7 +138,7 @@ class WebSocketChannel::SendBuffer { // The total size of the payload data in |frames_|. This will be used to // measure the throughput of the link. // TODO(ricea): Measure the throughput of the link. - size_t total_bytes_; + uint64 total_bytes_; }; void WebSocketChannel::SendBuffer::AddFrame(scoped_ptr frame) { @@ -266,8 +266,8 @@ WebSocketChannel::PendingReceivedFrame::PendingReceivedFrame( bool final, WebSocketFrameHeader::OpCode opcode, const scoped_refptr& data, - size_t offset, - size_t size) + uint64 offset, + uint64 size) : final_(final), opcode_(opcode), data_(data), @@ -281,7 +281,7 @@ void WebSocketChannel::PendingReceivedFrame::ResetOpcode() { opcode_ = WebSocketFrameHeader::kOpCodeContinuation; } -void WebSocketChannel::PendingReceivedFrame::DidConsume(size_t bytes) { +void WebSocketChannel::PendingReceivedFrame::DidConsume(uint64 bytes) { DCHECK_LE(offset_, size_); DCHECK_LE(bytes, size_ - offset_); offset_ += bytes; @@ -419,13 +419,13 @@ void WebSocketChannel::SendFlowControl(int64 quota) { DCHECK_GE(quota, 0); DCHECK_LE(quota, INT_MAX); if (!pending_received_frames_.empty()) { - DCHECK_EQ(0, current_receive_quota_); + DCHECK_EQ(0u, current_receive_quota_); } while (!pending_received_frames_.empty() && quota > 0) { PendingReceivedFrame& front = pending_received_frames_.front(); - const size_t data_size = front.size() - front.offset(); - const size_t bytes_to_send = - std::min(base::checked_cast(quota), data_size); + const uint64 data_size = front.size() - front.offset(); + const uint64 bytes_to_send = + std::min(base::checked_cast(quota), data_size); const bool final = front.final() && data_size == bytes_to_send; const char* data = front.data().get() ? front.data()->data() + front.offset() : NULL; @@ -442,9 +442,7 @@ void WebSocketChannel::SendFlowControl(int64 quota) { front.ResetOpcode(); return; } - const int64 signed_bytes_to_send = base::checked_cast(bytes_to_send); - DCHECK_GE(quota, signed_bytes_to_send); - quota -= signed_bytes_to_send; + quota -= bytes_to_send; pending_received_frames_.pop(); } @@ -453,7 +451,7 @@ void WebSocketChannel::SendFlowControl(int64 quota) { const bool start_read = current_receive_quota_ == 0 && quota > 0 && (state_ == CONNECTED || state_ == SEND_CLOSED || state_ == CLOSE_WAIT); - current_receive_quota_ += base::checked_cast(quota); + current_receive_quota_ += quota; if (start_read) ignore_result(ReadFrames()); // |this| may have been deleted. @@ -790,7 +788,7 @@ ChannelState WebSocketChannel::HandleFrameByState( const WebSocketFrameHeader::OpCode opcode, bool final, const scoped_refptr& data_buffer, - size_t size) { + uint64 size) { DCHECK_NE(RECV_CLOSED, state_) << "HandleFrame() does not support being called re-entrantly from within " "SendClose()"; @@ -878,7 +876,7 @@ ChannelState WebSocketChannel::HandleDataFrame( WebSocketFrameHeader::OpCode opcode, bool final, const scoped_refptr& data_buffer, - size_t size) { + uint64 size) { if (state_ != CONNECTED) { DVLOG(3) << "Ignored data packet received in state " << state_; return CHANNEL_ALIVE; @@ -911,7 +909,7 @@ ChannelState WebSocketChannel::HandleDataFrame( // This call is not redundant when size == 0 because it tells us what // the current state is. StreamingUtf8Validator::State state = incoming_utf8_validator_.AddBytes( - size ? data_buffer->data() : NULL, size); + size ? data_buffer->data() : NULL, static_cast(size)); if (state == StreamingUtf8Validator::INVALID || (state == StreamingUtf8Validator::VALID_MIDPOINT && final)) { return FailChannel("Could not decode a text frame as UTF-8.", @@ -925,8 +923,7 @@ ChannelState WebSocketChannel::HandleDataFrame( return CHANNEL_ALIVE; initial_frame_forwarded_ = !final; - if (size > base::checked_cast(current_receive_quota_) || - !pending_received_frames_.empty()) { + if (size > current_receive_quota_ || !pending_received_frames_.empty()) { const bool no_quota = (current_receive_quota_ == 0); DCHECK(no_quota || pending_received_frames_.empty()); DVLOG(3) << "Queueing frame to renderer due to quota. quota=" @@ -946,7 +943,6 @@ ChannelState WebSocketChannel::HandleDataFrame( const char* const data_end = data_begin + size; const std::vector data(data_begin, data_end); current_receive_quota_ -= size; - DCHECK_GE(current_receive_quota_, 0); // Sends the received frame to the renderer process. return event_interface_->OnDataFrame(final, opcode_to_send, data); @@ -956,7 +952,7 @@ ChannelState WebSocketChannel::SendFrameFromIOBuffer( bool fin, WebSocketFrameHeader::OpCode op_code, const scoped_refptr& buffer, - size_t size) { + uint64 size) { DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED); DCHECK(stream_); @@ -1009,7 +1005,7 @@ ChannelState WebSocketChannel::SendClose(uint16 code, DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED); DCHECK_LE(reason.size(), kMaximumCloseReasonLength); scoped_refptr body; - size_t size = 0; + uint64 size = 0; if (code == kWebSocketErrorNoStatusReceived) { // Special case: translate kWebSocketErrorNoStatusReceived into a Close // frame with no payload. @@ -1039,7 +1035,7 @@ ChannelState WebSocketChannel::SendClose(uint16 code, } bool WebSocketChannel::ParseClose(const scoped_refptr& buffer, - size_t size, + uint64 size, uint16* code, std::string* reason, std::string* message) { diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h index 6d5640e8be00f5..a79ec4b43f07b8 100644 --- a/net/websockets/websocket_channel.h +++ b/net/websockets/websocket_channel.h @@ -130,8 +130,8 @@ class NET_EXPORT WebSocketChannel { PendingReceivedFrame(bool final, WebSocketFrameHeader::OpCode opcode, const scoped_refptr& data, - size_t offset, - size_t size); + uint64 offset, + uint64 size); ~PendingReceivedFrame(); bool final() const { return final_; } @@ -139,10 +139,10 @@ class NET_EXPORT WebSocketChannel { // ResetOpcode() to Continuation. void ResetOpcode(); const scoped_refptr& data() const { return data_; } - size_t offset() const { return offset_; } - size_t size() const { return size_; } + uint64 offset() const { return offset_; } + uint64 size() const { return size_; } // Increase |offset_| by |bytes|. - void DidConsume(size_t bytes); + void DidConsume(uint64 bytes); // This object needs to be copyable and assignable, since it will be placed // in a std::queue. The compiler-generated copy constructor and assignment @@ -154,9 +154,9 @@ class NET_EXPORT WebSocketChannel { scoped_refptr data_; // Where to start reading from data_. Everything prior to offset_ has // already been sent to the browser. - size_t offset_; + uint64 offset_; // The size of data_. - size_t size_; + uint64 size_; }; // Methods which return a value of type ChannelState may delete |this|. If the @@ -259,7 +259,7 @@ class NET_EXPORT WebSocketChannel { const WebSocketFrameHeader::OpCode opcode, bool final, const scoped_refptr& data_buffer, - size_t size) WARN_UNUSED_RESULT; + uint64 size) WARN_UNUSED_RESULT; // Forward a received data frame to the renderer, if connected. If // |expecting_continuation| is not equal to |expecting_to_read_continuation_|, @@ -267,7 +267,7 @@ class NET_EXPORT WebSocketChannel { ChannelState HandleDataFrame(WebSocketFrameHeader::OpCode opcode, bool final, const scoped_refptr& data_buffer, - size_t size) WARN_UNUSED_RESULT; + uint64 size) WARN_UNUSED_RESULT; // Low-level method to send a single frame. Used for both data and control // frames. Either sends the frame immediately or buffers it to be scheduled @@ -277,7 +277,7 @@ class NET_EXPORT WebSocketChannel { ChannelState SendFrameFromIOBuffer(bool fin, WebSocketFrameHeader::OpCode op_code, const scoped_refptr& buffer, - size_t size) WARN_UNUSED_RESULT; + uint64 size) WARN_UNUSED_RESULT; // Performs the "Fail the WebSocket Connection" operation as defined in // RFC6455. A NotifyFailure message is sent to the renderer with |message|. @@ -306,7 +306,7 @@ class NET_EXPORT WebSocketChannel { // then false is returned and |message| is set to an appropriate console // message. bool ParseClose(const scoped_refptr& buffer, - size_t size, + uint64 size, uint16* code, std::string* reason, std::string* message); @@ -368,7 +368,7 @@ class NET_EXPORT WebSocketChannel { int current_send_quota_; // The remaining amount of quota that the renderer will allow us to send on // this logical channel (quota units). - int current_receive_quota_; + uint64 current_receive_quota_; // Timer for the closing handshake. base::OneShotTimer timer_; diff --git a/net/websockets/websocket_deflate_stream.cc b/net/websockets/websocket_deflate_stream.cc index f3d293a273f002..6666bef0aea169 100644 --- a/net/websockets/websocket_deflate_stream.cc +++ b/net/websockets/websocket_deflate_stream.cc @@ -133,8 +133,9 @@ int WebSocketDeflateStream::Deflate(ScopedVector* frames) { current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; } else { if (frame->data.get() && - !deflater_.AddBytes(frame->data->data(), - frame->header.payload_length)) { + !deflater_.AddBytes( + frame->data->data(), + static_cast(frame->header.payload_length))) { DVLOG(1) << "WebSocket protocol error. " << "deflater_.AddBytes() returns an error."; return ERR_WS_PROTOCOL_ERROR; @@ -312,8 +313,9 @@ int WebSocketDeflateStream::Inflate(ScopedVector* frames) { } else { DCHECK_EQ(reading_state_, READING_COMPRESSED_MESSAGE); if (frame->data.get() && - !inflater_.AddBytes(frame->data->data(), - frame->header.payload_length)) { + !inflater_.AddBytes( + frame->data->data(), + static_cast(frame->header.payload_length))) { DVLOG(1) << "WebSocket protocol error. " << "inflater_.AddBytes() returns an error."; return ERR_WS_PROTOCOL_ERROR; diff --git a/net/websockets/websocket_frame_parser.cc b/net/websockets/websocket_frame_parser.cc index 2e4c58fe3023ce..d00a1d11ae59bf 100644 --- a/net/websockets/websocket_frame_parser.cc +++ b/net/websockets/websocket_frame_parser.cc @@ -171,13 +171,11 @@ void WebSocketFrameParser::DecodeFrameHeader() { scoped_ptr WebSocketFrameParser::DecodeFramePayload( bool first_chunk) { - const char* current = &buffer_.front() + current_read_pos_; - const char* end = &buffer_.front() + buffer_.size(); - uint64 next_size = std::min( - end - current, current_frame_header_->payload_length - frame_offset_); - // This check must pass because |payload_length| is already checked to be + // The cast here is safe because |payload_length| is already checked to be // less than std::numeric_limits::max() when the header is parsed. - DCHECK_LE(next_size, static_cast(kint32max)); + int next_size = static_cast(std::min( + static_cast(buffer_.size() - current_read_pos_), + current_frame_header_->payload_length - frame_offset_)); scoped_ptr frame_chunk(new WebSocketFrameChunk); if (first_chunk) { @@ -187,7 +185,7 @@ scoped_ptr WebSocketFrameParser::DecodeFramePayload( if (next_size) { frame_chunk->data = new IOBufferWithSize(static_cast(next_size)); char* io_data = frame_chunk->data->data(); - memcpy(io_data, current, next_size); + memcpy(io_data, &buffer_.front() + current_read_pos_, next_size); if (current_frame_header_->masked) { // The masking function is its own inverse, so we use the same function to // unmask as to mask.