Skip to content

Commit

Permalink
Fix type truncation warnings related to WebSocketFrameHeader::payload…
Browse files Browse the repository at this point in the history
…_length

being a uint64.

BUG=81439
TEST=none

Review URL: https://codereview.chromium.org/653713002

Cr-Commit-Position: refs/heads/master@{#299713}
  • Loading branch information
pkasting authored and Commit bot committed Oct 15, 2014
1 parent 14ae054 commit 4bff6be
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 52 deletions.
16 changes: 8 additions & 8 deletions net/websockets/websocket_basic_stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,22 @@ typedef ScopedVector<WebSocketFrame>::const_iterator WebSocketFrameIterator;
// masked bit of the frames on.
int CalculateSerializedSizeAndTurnOnMaskBit(
ScopedVector<WebSocketFrame>* frames) {
const int kMaximumTotalSize = std::numeric_limits<int>::max();
const uint64 kMaximumTotalSize = std::numeric_limits<int>::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<int>(total_size);
}

} // namespace
Expand Down Expand Up @@ -157,9 +157,9 @@ int WebSocketBasicStream::WriteFrames(ScopedVector<WebSocketFrame>* frames,
dest += result;
remaining_size -= result;

const int frame_size = frame->header.payload_length;
CHECK_LE(frame->header.payload_length, static_cast<uint64>(remaining_size));
const int frame_size = static_cast<int>(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);
Expand Down
38 changes: 17 additions & 21 deletions net/websockets/websocket_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<WebSocketFrame> frame) {
Expand Down Expand Up @@ -266,8 +266,8 @@ WebSocketChannel::PendingReceivedFrame::PendingReceivedFrame(
bool final,
WebSocketFrameHeader::OpCode opcode,
const scoped_refptr<IOBuffer>& data,
size_t offset,
size_t size)
uint64 offset,
uint64 size)
: final_(final),
opcode_(opcode),
data_(data),
Expand All @@ -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;
Expand Down Expand Up @@ -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<size_t>(quota), data_size);
const uint64 data_size = front.size() - front.offset();
const uint64 bytes_to_send =
std::min(base::checked_cast<uint64>(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;
Expand All @@ -442,9 +442,7 @@ void WebSocketChannel::SendFlowControl(int64 quota) {
front.ResetOpcode();
return;
}
const int64 signed_bytes_to_send = base::checked_cast<int64>(bytes_to_send);
DCHECK_GE(quota, signed_bytes_to_send);
quota -= signed_bytes_to_send;
quota -= bytes_to_send;

pending_received_frames_.pop();
}
Expand All @@ -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<int>(quota);
current_receive_quota_ += quota;
if (start_read)
ignore_result(ReadFrames());
// |this| may have been deleted.
Expand Down Expand Up @@ -790,7 +788,7 @@ ChannelState WebSocketChannel::HandleFrameByState(
const WebSocketFrameHeader::OpCode opcode,
bool final,
const scoped_refptr<IOBuffer>& data_buffer,
size_t size) {
uint64 size) {
DCHECK_NE(RECV_CLOSED, state_)
<< "HandleFrame() does not support being called re-entrantly from within "
"SendClose()";
Expand Down Expand Up @@ -878,7 +876,7 @@ ChannelState WebSocketChannel::HandleDataFrame(
WebSocketFrameHeader::OpCode opcode,
bool final,
const scoped_refptr<IOBuffer>& data_buffer,
size_t size) {
uint64 size) {
if (state_ != CONNECTED) {
DVLOG(3) << "Ignored data packet received in state " << state_;
return CHANNEL_ALIVE;
Expand Down Expand Up @@ -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_t>(size));
if (state == StreamingUtf8Validator::INVALID ||
(state == StreamingUtf8Validator::VALID_MIDPOINT && final)) {
return FailChannel("Could not decode a text frame as UTF-8.",
Expand All @@ -925,8 +923,7 @@ ChannelState WebSocketChannel::HandleDataFrame(
return CHANNEL_ALIVE;

initial_frame_forwarded_ = !final;
if (size > base::checked_cast<size_t>(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="
Expand All @@ -946,7 +943,6 @@ ChannelState WebSocketChannel::HandleDataFrame(
const char* const data_end = data_begin + size;
const std::vector<char> 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);
Expand All @@ -956,7 +952,7 @@ ChannelState WebSocketChannel::SendFrameFromIOBuffer(
bool fin,
WebSocketFrameHeader::OpCode op_code,
const scoped_refptr<IOBuffer>& buffer,
size_t size) {
uint64 size) {
DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
DCHECK(stream_);

Expand Down Expand Up @@ -1009,7 +1005,7 @@ ChannelState WebSocketChannel::SendClose(uint16 code,
DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
DCHECK_LE(reason.size(), kMaximumCloseReasonLength);
scoped_refptr<IOBuffer> body;
size_t size = 0;
uint64 size = 0;
if (code == kWebSocketErrorNoStatusReceived) {
// Special case: translate kWebSocketErrorNoStatusReceived into a Close
// frame with no payload.
Expand Down Expand Up @@ -1039,7 +1035,7 @@ ChannelState WebSocketChannel::SendClose(uint16 code,
}

bool WebSocketChannel::ParseClose(const scoped_refptr<IOBuffer>& buffer,
size_t size,
uint64 size,
uint16* code,
std::string* reason,
std::string* message) {
Expand Down
24 changes: 12 additions & 12 deletions net/websockets/websocket_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,19 @@ class NET_EXPORT WebSocketChannel {
PendingReceivedFrame(bool final,
WebSocketFrameHeader::OpCode opcode,
const scoped_refptr<IOBuffer>& data,
size_t offset,
size_t size);
uint64 offset,
uint64 size);
~PendingReceivedFrame();

bool final() const { return final_; }
WebSocketFrameHeader::OpCode opcode() const { return opcode_; }
// ResetOpcode() to Continuation.
void ResetOpcode();
const scoped_refptr<IOBuffer>& 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
Expand All @@ -154,9 +154,9 @@ class NET_EXPORT WebSocketChannel {
scoped_refptr<IOBuffer> 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
Expand Down Expand Up @@ -259,15 +259,15 @@ class NET_EXPORT WebSocketChannel {
const WebSocketFrameHeader::OpCode opcode,
bool final,
const scoped_refptr<IOBuffer>& 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_|,
// will fail the channel. Also checks the UTF-8 validity of text frames.
ChannelState HandleDataFrame(WebSocketFrameHeader::OpCode opcode,
bool final,
const scoped_refptr<IOBuffer>& 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
Expand All @@ -277,7 +277,7 @@ class NET_EXPORT WebSocketChannel {
ChannelState SendFrameFromIOBuffer(bool fin,
WebSocketFrameHeader::OpCode op_code,
const scoped_refptr<IOBuffer>& 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|.
Expand Down Expand Up @@ -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<IOBuffer>& buffer,
size_t size,
uint64 size,
uint16* code,
std::string* reason,
std::string* message);
Expand Down Expand Up @@ -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<WebSocketChannel> timer_;
Expand Down
10 changes: 6 additions & 4 deletions net/websockets/websocket_deflate_stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,9 @@ int WebSocketDeflateStream::Deflate(ScopedVector<WebSocketFrame>* 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<size_t>(frame->header.payload_length))) {
DVLOG(1) << "WebSocket protocol error. "
<< "deflater_.AddBytes() returns an error.";
return ERR_WS_PROTOCOL_ERROR;
Expand Down Expand Up @@ -312,8 +313,9 @@ int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* 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<size_t>(frame->header.payload_length))) {
DVLOG(1) << "WebSocket protocol error. "
<< "inflater_.AddBytes() returns an error.";
return ERR_WS_PROTOCOL_ERROR;
Expand Down
12 changes: 5 additions & 7 deletions net/websockets/websocket_frame_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,11 @@ void WebSocketFrameParser::DecodeFrameHeader() {

scoped_ptr<WebSocketFrameChunk> 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<uint64>(
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<int>::max() when the header is parsed.
DCHECK_LE(next_size, static_cast<uint64>(kint32max));
int next_size = static_cast<int>(std::min(
static_cast<uint64>(buffer_.size() - current_read_pos_),
current_frame_header_->payload_length - frame_offset_));

scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk);
if (first_chunk) {
Expand All @@ -187,7 +185,7 @@ scoped_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload(
if (next_size) {
frame_chunk->data = new IOBufferWithSize(static_cast<int>(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.
Expand Down

0 comments on commit 4bff6be

Please sign in to comment.