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

Side by Side Diff: net/websockets/websocket_frame_parser.cc

Issue 10824081: Add WebSocketError to indicate decoding failure reason (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed, ready for commit Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/websockets/websocket_frame_parser.h" 5 #include "net/websockets/websocket_frame_parser.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 18 matching lines...) Expand all
29 const uint64 kPayloadLengthWithTwoByteExtendedLengthField = 126; 29 const uint64 kPayloadLengthWithTwoByteExtendedLengthField = 126;
30 const uint64 kPayloadLengthWithEightByteExtendedLengthField = 127; 30 const uint64 kPayloadLengthWithEightByteExtendedLengthField = 127;
31 31
32 } // Unnamed namespace. 32 } // Unnamed namespace.
33 33
34 namespace net { 34 namespace net {
35 35
36 WebSocketFrameParser::WebSocketFrameParser() 36 WebSocketFrameParser::WebSocketFrameParser()
37 : current_read_pos_(0), 37 : current_read_pos_(0),
38 frame_offset_(0), 38 frame_offset_(0),
39 failed_(false) { 39 websocket_error_(WEB_SOCKET_OK) {
40 std::fill(masking_key_, 40 std::fill(masking_key_,
41 masking_key_ + WebSocketFrameHeader::kMaskingKeyLength, 41 masking_key_ + WebSocketFrameHeader::kMaskingKeyLength,
42 '\0'); 42 '\0');
43 } 43 }
44 44
45 WebSocketFrameParser::~WebSocketFrameParser() { 45 WebSocketFrameParser::~WebSocketFrameParser() {
46 } 46 }
47 47
48 bool WebSocketFrameParser::Decode( 48 bool WebSocketFrameParser::Decode(
49 const char* data, 49 const char* data,
50 size_t length, 50 size_t length,
51 ScopedVector<WebSocketFrameChunk>* frame_chunks) { 51 ScopedVector<WebSocketFrameChunk>* frame_chunks) {
52 if (failed_) 52 if (websocket_error_ != WEB_SOCKET_OK)
53 return false; 53 return false;
54 if (!length) 54 if (!length)
55 return true; 55 return true;
56 56
57 // TODO(yutak): Remove copy. 57 // TODO(yutak): Remove copy.
58 buffer_.insert(buffer_.end(), data, data + length); 58 buffer_.insert(buffer_.end(), data, data + length);
59 59
60 while (current_read_pos_ < buffer_.size()) { 60 while (current_read_pos_ < buffer_.size()) {
61 bool first_chunk = false; 61 bool first_chunk = false;
62 if (!current_frame_header_.get()) { 62 if (!current_frame_header_.get()) {
63 DecodeFrameHeader(); 63 DecodeFrameHeader();
64 if (failed_) 64 if (websocket_error_ != WEB_SOCKET_OK)
65 return false; 65 return false;
66 // If frame header is incomplete, then carry over the remaining 66 // If frame header is incomplete, then carry over the remaining
67 // data to the next round of Decode(). 67 // data to the next round of Decode().
68 if (!current_frame_header_.get()) 68 if (!current_frame_header_.get())
69 break; 69 break;
70 first_chunk = true; 70 first_chunk = true;
71 } 71 }
72 72
73 scoped_ptr<WebSocketFrameChunk> frame_chunk = 73 scoped_ptr<WebSocketFrameChunk> frame_chunk =
74 DecodeFramePayload(first_chunk); 74 DecodeFramePayload(first_chunk);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 uint8 second_byte = *current++; 114 uint8 second_byte = *current++;
115 115
116 bool final = (first_byte & kFinalBit) != 0; 116 bool final = (first_byte & kFinalBit) != 0;
117 bool reserved1 = (first_byte & kReserved1Bit) != 0; 117 bool reserved1 = (first_byte & kReserved1Bit) != 0;
118 bool reserved2 = (first_byte & kReserved2Bit) != 0; 118 bool reserved2 = (first_byte & kReserved2Bit) != 0;
119 bool reserved3 = (first_byte & kReserved3Bit) != 0; 119 bool reserved3 = (first_byte & kReserved3Bit) != 0;
120 OpCode opcode = first_byte & kOpCodeMask; 120 OpCode opcode = first_byte & kOpCodeMask;
121 121
122 bool masked = (second_byte & kMaskBit) != 0; 122 bool masked = (second_byte & kMaskBit) != 0;
123 uint64 payload_length = second_byte & kPayloadLengthMask; 123 uint64 payload_length = second_byte & kPayloadLengthMask;
124 bool valid_length_format = true;
125 bool message_too_big = false;
126 if (payload_length == kPayloadLengthWithTwoByteExtendedLengthField) { 124 if (payload_length == kPayloadLengthWithTwoByteExtendedLengthField) {
127 if (end - current < 2) 125 if (end - current < 2)
128 return; 126 return;
129 uint16 payload_length_16; 127 uint16 payload_length_16;
130 ReadBigEndian(current, &payload_length_16); 128 ReadBigEndian(current, &payload_length_16);
131 current += 2; 129 current += 2;
132 payload_length = payload_length_16; 130 payload_length = payload_length_16;
133 if (payload_length <= kMaxPayloadLengthWithoutExtendedLengthField) 131 if (payload_length <= kMaxPayloadLengthWithoutExtendedLengthField)
134 valid_length_format = false; 132 websocket_error_ = WEB_SOCKET_ERR_PROTOCOL_ERROR;
135 } else if (payload_length == kPayloadLengthWithEightByteExtendedLengthField) { 133 } else if (payload_length == kPayloadLengthWithEightByteExtendedLengthField) {
136 if (end - current < 8) 134 if (end - current < 8)
137 return; 135 return;
138 ReadBigEndian(current, &payload_length); 136 ReadBigEndian(current, &payload_length);
139 current += 8; 137 current += 8;
140 if (payload_length <= kuint16max || 138 if (payload_length <= kuint16max ||
141 payload_length > static_cast<uint64>(kint64max)) { 139 payload_length > static_cast<uint64>(kint64max)) {
142 valid_length_format = false; 140 websocket_error_ = WEB_SOCKET_ERR_PROTOCOL_ERROR;
141 } else if (payload_length > static_cast<uint64>(kint32max)) {
142 websocket_error_ = WEB_SOCKET_ERR_MESSAGE_TOO_BIG;
143 } 143 }
144 if (payload_length > static_cast<uint64>(kint32max))
145 message_too_big = true;
146 } 144 }
147 if (!valid_length_format || message_too_big) { 145 if (websocket_error_ != WEB_SOCKET_OK) {
148 failed_ = true;
149 buffer_.clear(); 146 buffer_.clear();
150 current_read_pos_ = 0; 147 current_read_pos_ = 0;
151 current_frame_header_.reset(); 148 current_frame_header_.reset();
152 frame_offset_ = 0; 149 frame_offset_ = 0;
153 return; 150 return;
154 } 151 }
155 152
156 if (masked) { 153 if (masked) {
157 if (end - current < kMaskingKeyLength) 154 if (end - current < kMaskingKeyLength)
158 return; 155 return;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 if (frame_offset_ == current_frame_header_->payload_length) { 212 if (frame_offset_ == current_frame_header_->payload_length) {
216 frame_chunk->final_chunk = true; 213 frame_chunk->final_chunk = true;
217 current_frame_header_.reset(); 214 current_frame_header_.reset();
218 frame_offset_ = 0; 215 frame_offset_ = 0;
219 } 216 }
220 217
221 return frame_chunk.Pass(); 218 return frame_chunk.Pass();
222 } 219 }
223 220
224 } // namespace net 221 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_frame_parser.h ('k') | net/websockets/websocket_frame_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698