Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(635)

Unified Diff: net/websockets/websocket_channel.cc

Issue 157033013: Check for invalid use of data frame opcodes. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Remove |expecting_continuation| parameter from HandleDataFrame() Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/websockets/websocket_channel.h ('k') | net/websockets/websocket_channel_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/websockets/websocket_channel.cc
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc
index 9e255ab1f7a0fa5ad918896e8dc9ccd3fd44bb4e..d75c0a3728d19636ba445d8d144f3454e0baff1c 100644
--- a/net/websockets/websocket_channel.cc
+++ b/net/websockets/websocket_channel.cc
@@ -229,7 +229,8 @@ WebSocketChannel::WebSocketChannel(
state_(FRESHLY_CONSTRUCTED),
notification_sender_(new HandshakeNotificationSender(this)),
sending_text_message_(false),
- receiving_text_message_(false) {}
+ receiving_text_message_(false),
+ expecting_to_handle_continuation_(false) {}
WebSocketChannel::~WebSocketChannel() {
// The stream may hold a pointer to read_frames_, and so it needs to be
@@ -665,40 +666,9 @@ ChannelState WebSocketChannel::HandleFrame(
}
switch (opcode) {
case WebSocketFrameHeader::kOpCodeText: // fall-thru
- case WebSocketFrameHeader::kOpCodeBinary: // fall-thru
+ case WebSocketFrameHeader::kOpCodeBinary:
case WebSocketFrameHeader::kOpCodeContinuation:
- if (state_ == CONNECTED) {
- if (opcode == WebSocketFrameHeader::kOpCodeText ||
- (opcode == WebSocketFrameHeader::kOpCodeContinuation &&
- receiving_text_message_)) {
- // 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);
- if (state == StreamingUtf8Validator::INVALID ||
- (state == StreamingUtf8Validator::VALID_MIDPOINT && final)) {
- return FailChannel("Could not decode a text frame as UTF-8.",
- kWebSocketErrorProtocolError,
- "Invalid UTF-8 in text frame");
- }
- receiving_text_message_ = !final;
- DCHECK(!final || state == StreamingUtf8Validator::VALID_ENDPOINT);
- }
- // TODO(ricea): Can this copy be eliminated?
- const char* const data_begin = size ? data_buffer->data() : NULL;
- const char* const data_end = data_begin + size;
- const std::vector<char> data(data_begin, data_end);
- // TODO(ricea): Handle the case when ReadFrames returns far
- // more data at once than should be sent in a single IPC. This needs to
- // be handled carefully, as an overloaded IO thread is one possible
- // cause of receiving very large chunks.
-
- // Sends the received frame to the renderer process.
- return event_interface_->OnDataFrame(final, opcode, data);
- }
- VLOG(3) << "Ignored data packet received in state " << state_;
- return CHANNEL_ALIVE;
+ return HandleDataFrame(opcode, final, data_buffer, size);
case WebSocketFrameHeader::kOpCodePing:
VLOG(1) << "Got Ping of size " << size;
@@ -759,6 +729,59 @@ ChannelState WebSocketChannel::HandleFrame(
}
}
+ChannelState WebSocketChannel::HandleDataFrame(
+ const WebSocketFrameHeader::OpCode opcode,
+ bool final,
+ const scoped_refptr<IOBuffer>& data_buffer,
+ size_t size) {
+ if (state_ != CONNECTED) {
+ DVLOG(3) << "Ignored data packet received in state " << state_;
+ return CHANNEL_ALIVE;
+ }
+ DCHECK(opcode == WebSocketFrameHeader::kOpCodeContinuation ||
+ opcode == WebSocketFrameHeader::kOpCodeText ||
+ opcode == WebSocketFrameHeader::kOpCodeBinary);
+ const bool got_continuation =
+ (opcode == WebSocketFrameHeader::kOpCodeContinuation);
+ if (got_continuation != expecting_to_handle_continuation_) {
+ const std::string console_log = got_continuation
+ ? "Received unexpected continuation frame."
+ : "Received start of new message but previous message is unfinished.";
+ const std::string reason = got_continuation
+ ? "Unexpected continuation"
+ : "Previous data frame unfinished";
+ return FailChannel(console_log, kWebSocketErrorProtocolError, reason);
+ }
+ expecting_to_handle_continuation_ = !final;
+ if (opcode == WebSocketFrameHeader::kOpCodeText ||
+ (opcode == WebSocketFrameHeader::kOpCodeContinuation &&
+ receiving_text_message_)) {
+ // 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);
+ if (state == StreamingUtf8Validator::INVALID ||
+ (state == StreamingUtf8Validator::VALID_MIDPOINT && final)) {
+ return FailChannel("Could not decode a text frame as UTF-8.",
+ kWebSocketErrorProtocolError,
+ "Invalid UTF-8 in text frame");
+ }
+ receiving_text_message_ = !final;
+ DCHECK(!final || state == StreamingUtf8Validator::VALID_ENDPOINT);
+ }
+ // TODO(ricea): Can this copy be eliminated?
+ const char* const data_begin = size ? data_buffer->data() : NULL;
+ const char* const data_end = data_begin + size;
+ const std::vector<char> data(data_begin, data_end);
+ // TODO(ricea): Handle the case when ReadFrames returns far
+ // more data at once than should be sent in a single IPC. This needs to
+ // be handled carefully, as an overloaded IO thread is one possible
+ // cause of receiving very large chunks.
+
+ // Sends the received frame to the renderer process.
+ return event_interface_->OnDataFrame(final, opcode, data);
+}
+
ChannelState WebSocketChannel::SendIOBuffer(
bool fin,
WebSocketFrameHeader::OpCode op_code,
« no previous file with comments | « net/websockets/websocket_channel.h ('k') | net/websockets/websocket_channel_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698