OLD | NEW |
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" | |
11 #include "base/big_endian.h" | 10 #include "base/big_endian.h" |
12 #include "base/logging.h" | 11 #include "base/logging.h" |
13 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
14 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
15 #include "base/memory/scoped_vector.h" | 14 #include "base/memory/scoped_vector.h" |
16 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
17 #include "net/websockets/websocket_frame.h" | 16 #include "net/websockets/websocket_frame.h" |
18 | 17 |
19 namespace { | 18 namespace { |
20 | 19 |
21 const uint8_t kFinalBit = 0x80; | 20 const uint8_t kFinalBit = 0x80; |
22 const uint8_t kReserved1Bit = 0x40; | 21 const uint8_t kReserved1Bit = 0x40; |
23 const uint8_t kReserved2Bit = 0x20; | 22 const uint8_t kReserved2Bit = 0x20; |
24 const uint8_t kReserved3Bit = 0x10; | 23 const uint8_t kReserved3Bit = 0x10; |
25 const uint8_t kOpCodeMask = 0xF; | 24 const uint8_t kOpCodeMask = 0xF; |
26 const uint8_t kMaskBit = 0x80; | 25 const uint8_t kMaskBit = 0x80; |
27 const uint8_t kPayloadLengthMask = 0x7F; | 26 const uint8_t kPayloadLengthMask = 0x7F; |
28 const uint64_t kMaxPayloadLengthWithoutExtendedLengthField = 125; | 27 const uint64_t kMaxPayloadLengthWithoutExtendedLengthField = 125; |
29 const uint64_t kPayloadLengthWithTwoByteExtendedLengthField = 126; | 28 const uint64_t kPayloadLengthWithTwoByteExtendedLengthField = 126; |
30 const uint64_t kPayloadLengthWithEightByteExtendedLengthField = 127; | 29 const uint64_t kPayloadLengthWithEightByteExtendedLengthField = 127; |
31 | 30 |
32 } // Unnamed namespace. | 31 } // namespace. |
33 | 32 |
34 namespace net { | 33 namespace net { |
35 | 34 |
36 WebSocketFrameParser::WebSocketFrameParser() | 35 WebSocketFrameParser::WebSocketFrameParser() |
37 : current_read_pos_(0), | 36 : current_read_pos_(0), |
38 frame_offset_(0), | 37 frame_offset_(0), |
39 websocket_error_(kWebSocketNormalClosure) { | 38 websocket_error_(kWebSocketNormalClosure) { |
40 std::fill(masking_key_.key, | 39 std::fill(masking_key_.key, |
41 masking_key_.key + WebSocketFrameHeader::kMaskingKeyLength, | 40 masking_key_.key + WebSocketFrameHeader::kMaskingKeyLength, |
42 '\0'); | 41 '\0'); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 base::ReadBigEndian(current, &payload_length_16); | 126 base::ReadBigEndian(current, &payload_length_16); |
128 current += 2; | 127 current += 2; |
129 payload_length = payload_length_16; | 128 payload_length = payload_length_16; |
130 if (payload_length <= kMaxPayloadLengthWithoutExtendedLengthField) | 129 if (payload_length <= kMaxPayloadLengthWithoutExtendedLengthField) |
131 websocket_error_ = kWebSocketErrorProtocolError; | 130 websocket_error_ = kWebSocketErrorProtocolError; |
132 } else if (payload_length == kPayloadLengthWithEightByteExtendedLengthField) { | 131 } else if (payload_length == kPayloadLengthWithEightByteExtendedLengthField) { |
133 if (end - current < 8) | 132 if (end - current < 8) |
134 return; | 133 return; |
135 base::ReadBigEndian(current, &payload_length); | 134 base::ReadBigEndian(current, &payload_length); |
136 current += 8; | 135 current += 8; |
137 if (payload_length <= kuint16max || | 136 if (payload_length <= UINT16_MAX || |
138 payload_length > static_cast<uint64_t>(kint64max)) { | 137 payload_length > static_cast<uint64_t>(INT64_MAX)) { |
139 websocket_error_ = kWebSocketErrorProtocolError; | 138 websocket_error_ = kWebSocketErrorProtocolError; |
140 } else if (payload_length > static_cast<uint64_t>(kint32max)) { | 139 } else if (payload_length > static_cast<uint64_t>(INT32_MAX)) { |
141 websocket_error_ = kWebSocketErrorMessageTooBig; | 140 websocket_error_ = kWebSocketErrorMessageTooBig; |
142 } | 141 } |
143 } | 142 } |
144 if (websocket_error_ != kWebSocketNormalClosure) { | 143 if (websocket_error_ != kWebSocketNormalClosure) { |
145 buffer_.clear(); | 144 buffer_.clear(); |
146 current_read_pos_ = 0; | 145 current_read_pos_ = 0; |
147 current_frame_header_.reset(); | 146 current_frame_header_.reset(); |
148 frame_offset_ = 0; | 147 frame_offset_ = 0; |
149 return; | 148 return; |
150 } | 149 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 if (frame_offset_ == current_frame_header_->payload_length) { | 200 if (frame_offset_ == current_frame_header_->payload_length) { |
202 frame_chunk->final_chunk = true; | 201 frame_chunk->final_chunk = true; |
203 current_frame_header_.reset(); | 202 current_frame_header_.reset(); |
204 frame_offset_ = 0; | 203 frame_offset_ = 0; |
205 } | 204 } |
206 | 205 |
207 return frame_chunk.Pass(); | 206 return frame_chunk.Pass(); |
208 } | 207 } |
209 | 208 |
210 } // namespace net | 209 } // namespace net |
OLD | NEW |